[Scummvm-git-logs] scummvm master -> 3964a56ee3d91bf959ec9bfeb7c962f13fdca565
sev-
noreply at scummvm.org
Wed Apr 24 22:54:33 UTC 2024
This automated email contains information about 29 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
cf8034735e DEVTOOLS: director-generate-xobj-stub: Fix XObj::open() calling convention
2b170f60c5 DIRECTOR: XOBJ: Add stubs for Hell Cab libraries
abba88197c DIRECTOR: Fix start offset of wipe transitions
9d574a9e0e DIRECTOR: Add Paco video player for Hell Cab
461f39508a DIRECTOR: Sort output of the "vars" debugger command
df1dbd33be DIRECTOR: Always resize bitmap Sprite when setting cast member
ea089282c7 DIRECTOR: Set the _stretch Sprite flag when loading frames
eb5b867b36 DIRECTOR: Refactor Channel::getBbox
4a552fd61c DIRECTOR: Add Mean City to detection table
f92f78ef9a DIRECTOR: Fix Sprite::checkSpriteType for film loops
fa2e5ac9de DIRECTOR: Fix FilmLoopCastMember::getSubChannels
8ebfb3a2ea DIRECTOR: Fix digital video playback state leak
bf3947c19a DIRECTOR: Fix loading of 1-bit images with DIBDecoder
1d44f6892b VIDEO: PACo decoder: Add bounds and null checks
c49c10e881 DIRECTOR: Enable kLPPTrimGarbage for D2/D3 scripts
32d6c312ce DIRECTOR: Add 15fps quirk for Hell Cab
91857fecb4 IMAGES: Add Indeo 3 to QuickTime codec list
517a1563df DIRECTOR: Make sprite dragging relative to the mouse click
21bc268d49 DIRECTOR: Add CD detection quirk for PAWS
565be3d3c9 DIRECTOR: Cache cast member when processing mouseDown/mouseUp
c7e4f6737a DIRECTOR: LINGO: Allow negateData for VOID
0ae7c151b4 DIRECTOR: Fix DigitalVideoCastMember frame buffering
c8d8facf01 DIRECTOR: Always disable loop flag for linked sounds
2feaae3b93 DIRECTOR: XOBJ: Add XObjects for Virtual Nightclub
d27af65eb2 DIRECTOR: Make Virtual Nightclub run in 32bpp
89ba335860 DIRECTOR: XOBJ: Make object name match library name
616b63aa8f DIRECTOR: XOBJ: Add drive type detection to InstObj
54c6bd2636 DIRECTOR: Add framework for duplicating cast members
3964a56ee3 DIRECTOR: Add 16-bit quirk for Virtual Nightclub
Commit: cf8034735e0dc212bf9c6ef2d131f595a5bd4078
https://github.com/scummvm/scummvm/commit/cf8034735e0dc212bf9c6ef2d131f595a5bd4078
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DEVTOOLS: director-generate-xobj-stub: Fix XObj::open() calling convention
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 139e551fcba..053e20257a1 100755
--- a/devtools/director-generate-xobj-stub.py
+++ b/devtools/director-generate-xobj-stub.py
@@ -75,7 +75,7 @@ namespace {xobj_class} {{
extern const char *xlibName;
extern const char *fileNames[];
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
void close(ObjectType type);
{methlist}
@@ -139,7 +139,7 @@ static BuiltinProto xlibTopLevel[] = {{
_objType = ObjectType;
}}
-void {xobj_class}::open(ObjectType type) {{
+void {xobj_class}::open(ObjectType type, const Common::Path &path) {{
{xobject_class}::initMethods(xlibMethods);
{xobject_class} *xobj = new {xobject_class}(type);
g_lingo->exposeXObject(xlibName, xobj);
@@ -181,7 +181,7 @@ namespace {xobj_class} {{
extern const char *xlibName;
extern const char *fileNames[];
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
void close(ObjectType type);
{methlist}
@@ -225,7 +225,7 @@ static BuiltinProto builtins[] = {{
{{ nullptr, nullptr, 0, 0, 0, VOIDSYM }}
}};
-void {xobj_class}::open(ObjectType type) {{
+void {xobj_class}::open(ObjectType type, const Common::Path &path) {{
g_lingo->initBuiltIns(builtins);
}}
Commit: 2b170f60c5b2e2910fcf0951ca3784d4fde38c16
https://github.com/scummvm/scummvm/commit/2b170f60c5b2e2910fcf0951ca3784d4fde38c16
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: XOBJ: Add stubs for Hell Cab libraries
Changed paths:
A engines/director/lingo/xlibs/paco.cpp
A engines/director/lingo/xlibs/paco.h
A engines/director/lingo/xlibs/xwin.cpp
A engines/director/lingo/xlibs/xwin.h
engines/director/lingo/lingo-object.cpp
engines/director/lingo/xlibs/dpwavi.cpp
engines/director/lingo/xlibs/dpwavi.h
engines/director/lingo/xlibs/dpwqtw.cpp
engines/director/lingo/xlibs/dpwqtw.h
engines/director/module.mk
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 79236c223b2..74ff61b5464 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -86,6 +86,7 @@
#include "director/lingo/xlibs/movutils.h"
#include "director/lingo/xlibs/openbleedwindowxcmd.h"
#include "director/lingo/xlibs/orthoplayxobj.h"
+#include "director/lingo/xlibs/paco.h"
#include "director/lingo/xlibs/palxobj.h"
#include "director/lingo/xlibs/panel.h"
#include "director/lingo/xlibs/popupmenuxobj.h"
@@ -117,6 +118,7 @@
#include "director/lingo/xlibs/xio.h"
#include "director/lingo/xlibs/xplayanim.h"
#include "director/lingo/xlibs/xsoundxfcn.h"
+#include "director/lingo/xlibs/xwin.h"
#include "director/lingo/xlibs/yasix.h"
#include "director/lingo/xtras/scrnutil.h"
@@ -196,17 +198,17 @@ static struct XLibProto {
{ BatQT::fileNames, BatQT::open, BatQT::close, kXObj, 400 }, // D4
{ BlitPictXObj::fileNames, BlitPictXObj::open, BlitPictXObj::close, kXObj, 400 }, // D4
{ CDROMXObj::fileNames, CDROMXObj::open, CDROMXObj::close, kXObj, 200 }, // D2
- { CloseBleedWindowXCMD::fileNames, CloseBleedWindowXCMD::open, CloseBleedWindowXCMD::close, kXObj, 300 }, // D3
+ { CloseBleedWindowXCMD::fileNames, CloseBleedWindowXCMD::open, CloseBleedWindowXCMD::close,kXObj, 300 }, // D3
{ ColorXObj::fileNames, ColorXObj::open, ColorXObj::close, kXObj, 400 }, // D4
{ ColorCursorXObj::fileNames, ColorCursorXObj::open, ColorCursorXObj::close, kXObj, 400 }, // D4
{ ConsumerXObj::fileNames, ConsumerXObj::open, ConsumerXObj::close, kXObj, 400 }, // D4
{ CursorXObj::fileNames, CursorXObj::open, CursorXObj::close, kXObj, 400 }, // D4
+ { DPWAVIXObj::fileNames, DPWAVIXObj::open, DPWAVIXObj::close, kXObj, 300 }, // D3
+ { DPWQTWXObj::fileNames, DPWQTWXObj::open, DPWQTWXObj::close, kXObj, 300 }, // D3
{ DarkenScreen::fileNames, DarkenScreen::open, DarkenScreen::close, kXObj, 300 }, // D3
{ DeveloperStack::fileNames, DeveloperStack::open, DeveloperStack::close, kXObj, 300 }, // D3
{ DialogsXObj::fileNames, DialogsXObj::open, DialogsXObj::close, kXObj, 400 }, // D4
{ DirUtilXObj::fileNames, DirUtilXObj::open, DirUtilXObj::close, kXObj, 400 }, // D4
- { DPwAVI::fileNames, DPwAVI::open, DPwAVI::close, kXObj, 400 }, // D4
- { DPwQTw::fileNames, DPwQTw::open, DPwQTw::close, kXObj, 400 }, // D4
{ DrawXObj::fileNames, DrawXObj::open, DrawXObj::close, kXObj, 400 }, // D4
{ Ednox::fileNames, Ednox::open, Ednox::close, kXObj, 300 }, // D3
{ EventQXObj::fileNames, EventQXObj::open, EventQXObj::close, kXObj, 400 }, // D4
@@ -224,8 +226,8 @@ static struct XLibProto {
{ FinderEventsXCMD::fileNames, FinderEventsXCMD::open, FinderEventsXCMD::close, kXObj, 400 }, // D4
{ FlushXObj::fileNames, FlushXObj::open, FlushXObj::close, kXObj, 300 }, // D3
{ FPlayXObj::fileNames, FPlayXObj::open, FPlayXObj::close, kXObj, 200 }, // D2
- { GetScreenRectsXFCN::fileNames, GetScreenRectsXFCN::open, GetScreenRectsXFCN::close, kXObj, 300 }, // D3
- { GetScreenSizeXFCN::fileNames, GetScreenSizeXFCN::open, GetScreenSizeXFCN::close, kXObj, 300 }, // D3
+ { GetScreenRectsXFCN::fileNames, GetScreenRectsXFCN::open, GetScreenRectsXFCN::close, kXObj, 300 }, // D3
+ { GetScreenSizeXFCN::fileNames, GetScreenSizeXFCN::open, GetScreenSizeXFCN::close, kXObj, 300 }, // D3
{ GpidXObj::fileNames, GpidXObj::open, GpidXObj::close, kXObj, 400 }, // D4
{ HitMap::fileNames, HitMap::open, HitMap::close, kXObj, 400 }, // D4
{ IsCD::fileNames, IsCD::open, IsCD::close, kXObj, 300 }, // D3
@@ -244,24 +246,25 @@ static struct XLibProto {
{ MoveMouseXObj::fileNames, MoveMouseXObj::open, MoveMouseXObj::close, kXObj, 400 }, // D4
{ MovieIdxXObj::fileNames, MovieIdxXObj::open, MovieIdxXObj::close, kXObj, 400 }, // D4
{ MovUtilsXObj::fileNames, MovUtilsXObj::open, MovUtilsXObj::close, kXObj, 400 }, // D4
- { OpenBleedWindowXCMD::fileNames, OpenBleedWindowXCMD::open, OpenBleedWindowXCMD::close, kXObj, 300 }, // D3
+ { OpenBleedWindowXCMD::fileNames, OpenBleedWindowXCMD::open, OpenBleedWindowXCMD::close, kXObj, 300 }, // D3
{ OrthoPlayXObj::fileNames, OrthoPlayXObj::open, OrthoPlayXObj::close, kXObj, 400 }, // D4
+ { PACoXObj::fileNames, PACoXObj::open, PACoXObj::close, kXObj, 300 }, // D3
{ PalXObj::fileNames, PalXObj::open, PalXObj::close, kXObj, 400 }, // D4
{ PanelXObj::fileNames, PanelXObj::open, PanelXObj::close, kXObj, 200 }, // D2
{ PopUpMenuXObj::fileNames, PopUpMenuXObj::open, PopUpMenuXObj::close, kXObj, 200 }, // D2
{ Porta::fileNames, Porta::open, Porta::close, kXObj, 300 }, // D3
- { PortaXCMD::fileNames, PortaXCMD::open, PortaXCMD::close, kXObj, 300 }, // D3
+ { PortaXCMD::fileNames, PortaXCMD::open, PortaXCMD::close, kXObj, 300 }, // D3
{ PrefPath::fileNames, PrefPath::open, PrefPath::close, kXObj, 400 }, // D4
{ PrintOMaticXObj::fileNames, PrintOMaticXObj::open, PrintOMaticXObj::close, kXObj, 400 }, // D4
- { ProcessXObj::fileNames, ProcessXObj::open, ProcessXObj::close, kXObj, 400 }, // D4
+ { ProcessXObj::fileNames, ProcessXObj::open, ProcessXObj::close, kXObj, 400 }, // D4
{ QTCatMoviePlayerXObj::fileNames, QTCatMoviePlayerXObj::open, QTCatMoviePlayerXObj::close,kXObj, 400 }, // D4
{ QTMovie::fileNames, QTMovie::open, QTMovie::close, kXObj, 400 }, // D4
{ QTVR::fileNames, QTVR::open, QTVR::close, kXObj, 400 }, // D4
{ Quicktime::fileNames, Quicktime::open, Quicktime::close, kXObj, 300 }, // D3
{ RearWindowXObj::fileNames, RearWindowXObj::open, RearWindowXObj::close, kXObj, 400 }, // D4
{ RegisterComponent::fileNames, RegisterComponent::open, RegisterComponent::close, kXObj, 400 }, // D4
- { RemixXCMD::fileNames, RemixXCMD::open, RemixXCMD::close, kXObj, 300 }, // D3
- { ScrnUtilXtra::fileNames, ScrnUtilXtra::open, ScrnUtilXtra::close, kXtraObj, 500 }, // D5
+ { RemixXCMD::fileNames, RemixXCMD::open, RemixXCMD::close, kXObj, 300 }, // D3
+ { ScrnUtilXtra::fileNames, ScrnUtilXtra::open, ScrnUtilXtra::close, kXtraObj, 500 }, // D5
{ SerialPortXObj::fileNames, SerialPortXObj::open, SerialPortXObj::close, kXObj, 200 }, // D2
{ SoundJam::fileNames, SoundJam::open, SoundJam::close, kXObj, 400 }, // D4
{ SpaceMgr::fileNames, SpaceMgr::open, SpaceMgr::close, kXObj, 400 }, // D4
@@ -276,6 +279,7 @@ static struct XLibProto {
{ WindowXObj::fileNames, WindowXObj::open, WindowXObj::close, kXObj, 200 }, // D2
{ XCMDGlueXObj::fileNames, XCMDGlueXObj::open, XCMDGlueXObj::close, kXObj, 200 }, // D2
{ XSoundXFCN::fileNames, XSoundXFCN::open, XSoundXFCN::close, kXObj, 400 }, // D4
+ { XWINXObj::fileNames, XWINXObj::open, XWINXObj::close, kXObj, 300 }, // D3
{ 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/dpwavi.cpp b/engines/director/lingo/xlibs/dpwavi.cpp
index 816b11c92b9..a6035dda982 100644
--- a/engines/director/lingo/xlibs/dpwavi.cpp
+++ b/engines/director/lingo/xlibs/dpwavi.cpp
@@ -19,22 +19,7 @@
*
*/
-/*************************************
-*
-* USED IN:
-* jman-win
-*
-*************************************/
-
-/*
- * -- AVI External Factory. 02oct92 JT
- * DPWAVI
- * X +mStartup -- First time init
- * X +mQuit -- Major bye bye
- * XI mNew qtPacket -- create a window
- * X mDispose -- close and dispose window
- * XII mVerb msg, qtPacker -- do something
- */
+#include "common/system.h"
#include "director/director.h"
#include "director/lingo/lingo.h"
@@ -42,58 +27,71 @@
#include "director/lingo/lingo-utils.h"
#include "director/lingo/xlibs/dpwavi.h"
+/**************************************************
+ *
+ * USED IN:
+ * jman-win
+ * hellcab-win
+ *
+ **************************************************/
+
+/*
+-- AVI External Factory. 02oct92 JT
+--DPWAVI
+X +mStartup -- First time init
+X +mQuit -- Major bye bye
+XI mNew qtPacket -- create a window
+X mDispose -- close and dispose window
+XII mVerb msg, qtPacker -- do something
+ */
namespace Director {
-// The name is different from the obj filename.
-const char *DPwAVI::xlibName = "dpwavi";
-const char *DPwAVI::fileNames[] = {
- "dpwavi",
+const char *DPWAVIXObj::xlibName = "DPWAVI";
+const char *DPWAVIXObj::fileNames[] = {
+ "DPWAVI",
nullptr
};
static MethodProto xlibMethods[] = {
- { "new", DPwAVI::m_new, 0, 1, 400 }, // D4
- { "startup", DPwAVI::m_startup, 0, 0, 400 }, // D4
- { "quit", DPwAVI::m_quit, 0, 0, 400 }, // D4
- { "verb", DPwAVI::m_verb, 2, 2, 400 }, // D4
+ { "startup", DPWAVIXObj::m_startup, 0, 0, 300 },
+ { "quit", DPWAVIXObj::m_quit, 0, 0, 300 },
+ { "new", DPWAVIXObj::m_new, 1, 1, 300 },
+ { "dispose", DPWAVIXObj::m_dispose, 0, 0, 300 },
+ { "verb", DPWAVIXObj::m_verb, 2, 2, 300 },
{ nullptr, nullptr, 0, 0, 0 }
};
-void DPwAVI::open(ObjectType type, const Common::Path &path) {
- if (type == kXObj) {
- DPwAVIXObject::initMethods(xlibMethods);
- DPwAVIXObject *xobj = new DPwAVIXObject(kXObj);
- g_lingo->exposeXObject(xlibName, xobj);
- }
+static BuiltinProto xlibBuiltins[] = {
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+DPWAVIXObject::DPWAVIXObject(ObjectType ObjectType) :Object<DPWAVIXObject>("DPWAVIXObj") {
+ _objType = ObjectType;
}
-void DPwAVI::close(ObjectType type) {
- if (type == kXObj) {
- DPwAVIXObject::cleanupMethods();
- g_lingo->_globalvars[xlibName] = Datum();
- }
+void DPWAVIXObj::open(ObjectType type, const Common::Path &path) {
+ DPWAVIXObject::initMethods(xlibMethods);
+ DPWAVIXObject *xobj = new DPWAVIXObject(type);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
}
+void DPWAVIXObj::close(ObjectType type) {
+ DPWAVIXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
-DPwAVIXObject::DPwAVIXObject(ObjectType ObjectType) : Object<DPwAVIXObject>("dpwavi") {
- _objType = ObjectType;
}
-void DPwAVI::m_new(int nargs) {
+void DPWAVIXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("DPWAVIXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
g_lingo->push(g_lingo->_state->me);
}
-void DPwAVI::m_startup(int nargs) {
- // no op
-}
-
-void DPwAVI::m_quit(int nargs) {
- // no op
-}
+XOBJSTUBNR(DPWAVIXObj::m_startup)
+XOBJSTUBNR(DPWAVIXObj::m_quit)
+XOBJSTUBNR(DPWAVIXObj::m_dispose)
+XOBJSTUBNR(DPWAVIXObj::m_verb)
-void DPwAVI::m_verb(int nargs) {
- g_lingo->printSTUBWithArglist("DPwAVI::m_verb", nargs);
}
-
-} // End of namespace Director
diff --git a/engines/director/lingo/xlibs/dpwavi.h b/engines/director/lingo/xlibs/dpwavi.h
index 5130d1e0b50..5a7f99e01aa 100644
--- a/engines/director/lingo/xlibs/dpwavi.h
+++ b/engines/director/lingo/xlibs/dpwavi.h
@@ -24,12 +24,12 @@
namespace Director {
-class DPwAVIXObject : public Object<DPwAVIXObject> {
+class DPWAVIXObject : public Object<DPWAVIXObject> {
public:
- DPwAVIXObject(ObjectType objType);
+ DPWAVIXObject(ObjectType objType);
};
-namespace DPwAVI {
+namespace DPWAVIXObj {
extern const char *xlibName;
extern const char *fileNames[];
@@ -37,12 +37,13 @@ extern const char *fileNames[];
void open(ObjectType type, const Common::Path &path);
void close(ObjectType type);
-void m_new(int nargs);
void m_startup(int nargs);
void m_quit(int nargs);
+void m_new(int nargs);
+void m_dispose(int nargs);
void m_verb(int nargs);
-} // End of namespace DPwAVI
+} // End of namespace DPWAVIXObj
} // End of namespace Director
diff --git a/engines/director/lingo/xlibs/dpwqtw.cpp b/engines/director/lingo/xlibs/dpwqtw.cpp
index dfcdbe9221f..32e6157bae2 100644
--- a/engines/director/lingo/xlibs/dpwqtw.cpp
+++ b/engines/director/lingo/xlibs/dpwqtw.cpp
@@ -19,80 +19,79 @@
*
*/
-/*************************************
-*
-* USED IN:
-* jman-win
-*
-*************************************/
-
-/**
- * -- QuickTime for Windows Player External Factory. 02oct92 JT
- * DPWQTW
- * X +mStartup -- First time init
- * X +mQuit -- Major bye bye
- * XI mNew qtPacket -- create a window
- * X mDispose -- close and dispose window
- * XII mVerb msg, qtPacker -- do something
- */
+#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/dpwqtw.h"
+/**************************************************
+ *
+ * USED IN:
+ * jman-win
+ * hellcab-win
+ *
+ **************************************************/
+
+/*
+-- QuickTime for Windows Player External Factory. 02oct92 JT
+--DPWQTW
+X +mStartup -- First time init
+X +mQuit -- Major bye bye
+XI mNew qtPacket -- create a window
+X mDispose -- close and dispose window
+XII mVerb msg, qtPacker -- do something
+ */
namespace Director {
-// The name is different from the obj filename.
-const char *DPwQTw::xlibName = "dpwqtw";
-const char *DPwQTw::fileNames[] = {
- "dpwqtw",
+const char *DPWQTWXObj::xlibName = "DPWQTW";
+const char *DPWQTWXObj::fileNames[] = {
+ "DPWQTW",
nullptr
};
static MethodProto xlibMethods[] = {
- { "new", DPwQTw::m_new, 0, 1, 400 }, // D4
- { "startup", DPwQTw::m_startup, 0, 0, 400 }, // D4
- { "quit", DPwQTw::m_quit, 0, 0, 400 }, // D4
- { "verb", DPwQTw::m_verb, 2, 2, 400 }, // D4
+ { "startup", DPWQTWXObj::m_startup, 0, 0, 300 },
+ { "quit", DPWQTWXObj::m_quit, 0, 0, 300 },
+ { "new", DPWQTWXObj::m_new, 1, 1, 300 },
+ { "dispose", DPWQTWXObj::m_dispose, 0, 0, 300 },
+ { "verb", DPWQTWXObj::m_verb, 2, 2, 300 },
{ nullptr, nullptr, 0, 0, 0 }
};
-void DPwQTw::open(ObjectType type, const Common::Path &path) {
- if (type == kXObj) {
- DPwQTwXObject::initMethods(xlibMethods);
- DPwQTwXObject *xobj = new DPwQTwXObject(kXObj);
- g_lingo->exposeXObject(xlibName, xobj);
- }
+static BuiltinProto xlibBuiltins[] = {
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+DPWQTWXObject::DPWQTWXObject(ObjectType ObjectType) :Object<DPWQTWXObject>("DPWQTWXObj") {
+ _objType = ObjectType;
}
-void DPwQTw::close(ObjectType type) {
- if (type == kXObj) {
- DPwQTwXObject::cleanupMethods();
- g_lingo->_globalvars[xlibName] = Datum();
- }
+void DPWQTWXObj::open(ObjectType type, const Common::Path &path) {
+ DPWQTWXObject::initMethods(xlibMethods);
+ DPWQTWXObject *xobj = new DPWQTWXObject(type);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
}
+void DPWQTWXObj::close(ObjectType type) {
+ DPWQTWXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
-DPwQTwXObject::DPwQTwXObject(ObjectType ObjectType) : Object<DPwQTwXObject>("dpwqtw") {
- _objType = ObjectType;
}
-void DPwQTw::m_new(int nargs) {
+void DPWQTWXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("DPWQTWXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
g_lingo->push(g_lingo->_state->me);
}
-void DPwQTw::m_startup(int nargs) {
- // no op
-}
-
-void DPwQTw::m_quit(int nargs) {
- // no op
-}
+XOBJSTUBNR(DPWQTWXObj::m_startup)
+XOBJSTUBNR(DPWQTWXObj::m_quit)
+XOBJSTUBNR(DPWQTWXObj::m_dispose)
+XOBJSTUBNR(DPWQTWXObj::m_verb)
-void DPwQTw::m_verb(int nargs) {
- g_lingo->printSTUBWithArglist("DPwQTw::m_verb", nargs);
}
-
-} // End of namespace Director
diff --git a/engines/director/lingo/xlibs/dpwqtw.h b/engines/director/lingo/xlibs/dpwqtw.h
index dcdeb061418..43f0811b834 100644
--- a/engines/director/lingo/xlibs/dpwqtw.h
+++ b/engines/director/lingo/xlibs/dpwqtw.h
@@ -24,12 +24,12 @@
namespace Director {
-class DPwQTwXObject : public Object<DPwQTwXObject> {
+class DPWQTWXObject : public Object<DPWQTWXObject> {
public:
- DPwQTwXObject(ObjectType objType);
+ DPWQTWXObject(ObjectType objType);
};
-namespace DPwQTw {
+namespace DPWQTWXObj {
extern const char *xlibName;
extern const char *fileNames[];
@@ -37,12 +37,13 @@ extern const char *fileNames[];
void open(ObjectType type, const Common::Path &path);
void close(ObjectType type);
-void m_new(int nargs);
void m_startup(int nargs);
void m_quit(int nargs);
+void m_new(int nargs);
+void m_dispose(int nargs);
void m_verb(int nargs);
-} // End of namespace DPwQTw
+} // End of namespace DPWQTWXObj
} // End of namespace Director
diff --git a/engines/director/lingo/xlibs/paco.cpp b/engines/director/lingo/xlibs/paco.cpp
new file mode 100644
index 00000000000..387b7262a0c
--- /dev/null
+++ b/engines/director/lingo/xlibs/paco.cpp
@@ -0,0 +1,90 @@
+/* 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/paco.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * hellcab-win
+ *
+ **************************************************/
+
+/*
+-- PACow External Factory. 15Jul93 JMU
+--PACo
+SS mNew, command --Creates a new instance of the XObject
+X mDispose --Disposes of XObject instance
+SSS mPACo, commands, results --Plays Paco movies
+ */
+
+namespace Director {
+
+const char *PACoXObj::xlibName = "PACo";
+const char *PACoXObj::fileNames[] = {
+ "PACO",
+ nullptr
+};
+
+static MethodProto xlibMethods[] = {
+ { "new", PACoXObj::m_new, 1, 1, 300 },
+ { "dispose", PACoXObj::m_dispose, 0, 0, 300 },
+ { "pACo", PACoXObj::m_pACo, 2, 2, 300 },
+ { nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+PACoXObject::PACoXObject(ObjectType ObjectType) :Object<PACoXObject>("PACoXObj") {
+ _objType = ObjectType;
+}
+
+void PACoXObj::open(ObjectType type, const Common::Path &path) {
+ PACoXObject::initMethods(xlibMethods);
+ PACoXObject *xobj = new PACoXObject(type);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void PACoXObj::close(ObjectType type) {
+ PACoXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void PACoXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("PACoXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
+ g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUBNR(PACoXObj::m_dispose)
+XOBJSTUB(PACoXObj::m_pACo, "")
+
+}
diff --git a/engines/director/lingo/xlibs/paco.h b/engines/director/lingo/xlibs/paco.h
new file mode 100644
index 00000000000..98e884ddba0
--- /dev/null
+++ b/engines/director/lingo/xlibs/paco.h
@@ -0,0 +1,48 @@
+/* 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_PACO_H
+#define DIRECTOR_LINGO_XLIBS_PACO_H
+
+namespace Director {
+
+class PACoXObject : public Object<PACoXObject> {
+public:
+ PACoXObject(ObjectType objType);
+};
+
+namespace PACoXObj {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_pACo(int nargs);
+
+} // End of namespace PACoXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/xwin.cpp b/engines/director/lingo/xlibs/xwin.cpp
new file mode 100644
index 00000000000..60fd8ff627f
--- /dev/null
+++ b/engines/director/lingo/xlibs/xwin.cpp
@@ -0,0 +1,144 @@
+/* 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/xwin.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * hellcab-win
+ *
+ **************************************************/
+
+/*
+-- XWIN External Factory. 9jul93 JU
+--XWIN
+I mNew --Creates a new instance of the XObject
+X mDispose --Disposes of XObject instance.
+II mWriteChar, charNum --Writes a single character. Returns error code
+IS mWriteString, string --Writes out a string of chars. Returns error code
+I mReadChar --Returns a single character
+S mReadWord --Returns the next word of an input file
+S mReadLine --Returns the next line of an input file
+S mReadFile --Returns the remainder of the file
+SSS mReadToken, breakString, skipString
+I mGetPosition --Returns the file position
+II mSetPosition, newPos --Sets the file position. Returns error code
+I mGetLength --Returns the number of chars in the file
+ISS mSetFinderInfo, typeString, creatorString
+S mGetFinderInfo --Gets the finder info
+S mFileName --Returns the name of the file
+I mDelete --Delete the file and dispose of me
+I mStatus --Returns result code of the last file io activity
+SI +mError, errorCode --Returns error message string
+V mReadPICT --Return handle to Metafile
+S mNativeFileName --Returns the native (dos) name of the file
+I mhwnd --window handle
+ */
+
+namespace Director {
+
+const char *XWINXObj::xlibName = "XWIN";
+const char *XWINXObj::fileNames[] = {
+ "XWIN",
+ nullptr
+};
+
+static MethodProto xlibMethods[] = {
+ { "new", XWINXObj::m_new, 0, 0, 300 },
+ { "dispose", XWINXObj::m_dispose, 0, 0, 300 },
+ { "writeChar", XWINXObj::m_writeChar, 1, 1, 300 },
+ { "writeString", XWINXObj::m_writeString, 1, 1, 300 },
+ { "readChar", XWINXObj::m_readChar, 0, 0, 300 },
+ { "readWord", XWINXObj::m_readWord, 0, 0, 300 },
+ { "readLine", XWINXObj::m_readLine, 0, 0, 300 },
+ { "readFile", XWINXObj::m_readFile, 0, 0, 300 },
+ { "readToken", XWINXObj::m_readToken, 2, 2, 300 },
+ { "getPosition", XWINXObj::m_getPosition, 0, 0, 300 },
+ { "setPosition", XWINXObj::m_setPosition, 1, 1, 300 },
+ { "getLength", XWINXObj::m_getLength, 0, 0, 300 },
+ { "setFinderInfo", XWINXObj::m_setFinderInfo, 2, 2, 300 },
+ { "getFinderInfo", XWINXObj::m_getFinderInfo, 0, 0, 300 },
+ { "fileName", XWINXObj::m_fileName, 0, 0, 300 },
+ { "delete", XWINXObj::m_delete, 0, 0, 300 },
+ { "status", XWINXObj::m_status, 0, 0, 300 },
+ { "error", XWINXObj::m_error, 1, 1, 300 },
+ { "readPICT", XWINXObj::m_readPICT, 0, 0, 300 },
+ { "nativeFileName", XWINXObj::m_nativeFileName, 0, 0, 300 },
+ { "hwnd", XWINXObj::m_hwnd, 0, 0, 300 },
+ { nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+XWINXObject::XWINXObject(ObjectType ObjectType) :Object<XWINXObject>("XWINXObj") {
+ _objType = ObjectType;
+}
+
+void XWINXObj::open(ObjectType type, const Common::Path &path) {
+ XWINXObject::initMethods(xlibMethods);
+ XWINXObject *xobj = new XWINXObject(type);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void XWINXObj::close(ObjectType type) {
+ XWINXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void XWINXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("XWINXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
+ g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUBNR(XWINXObj::m_dispose)
+XOBJSTUB(XWINXObj::m_writeChar, 0)
+XOBJSTUB(XWINXObj::m_writeString, 0)
+XOBJSTUB(XWINXObj::m_readChar, 0)
+XOBJSTUB(XWINXObj::m_readWord, "")
+XOBJSTUB(XWINXObj::m_readLine, "")
+XOBJSTUB(XWINXObj::m_readFile, "")
+XOBJSTUB(XWINXObj::m_readToken, "")
+XOBJSTUB(XWINXObj::m_getPosition, 0)
+XOBJSTUB(XWINXObj::m_setPosition, 0)
+XOBJSTUB(XWINXObj::m_getLength, 0)
+XOBJSTUB(XWINXObj::m_setFinderInfo, 0)
+XOBJSTUB(XWINXObj::m_getFinderInfo, "")
+XOBJSTUB(XWINXObj::m_fileName, "")
+XOBJSTUB(XWINXObj::m_delete, 0)
+XOBJSTUB(XWINXObj::m_status, 0)
+XOBJSTUB(XWINXObj::m_error, "")
+XOBJSTUB(XWINXObj::m_readPICT, 0)
+XOBJSTUB(XWINXObj::m_nativeFileName, "")
+XOBJSTUB(XWINXObj::m_hwnd, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/xwin.h b/engines/director/lingo/xlibs/xwin.h
new file mode 100644
index 00000000000..5c501ab265c
--- /dev/null
+++ b/engines/director/lingo/xlibs/xwin.h
@@ -0,0 +1,66 @@
+/* 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_XWIN_H
+#define DIRECTOR_LINGO_XLIBS_XWIN_H
+
+namespace Director {
+
+class XWINXObject : public Object<XWINXObject> {
+public:
+ XWINXObject(ObjectType objType);
+};
+
+namespace XWINXObj {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_writeChar(int nargs);
+void m_writeString(int nargs);
+void m_readChar(int nargs);
+void m_readWord(int nargs);
+void m_readLine(int nargs);
+void m_readFile(int nargs);
+void m_readToken(int nargs);
+void m_getPosition(int nargs);
+void m_setPosition(int nargs);
+void m_getLength(int nargs);
+void m_setFinderInfo(int nargs);
+void m_getFinderInfo(int nargs);
+void m_fileName(int nargs);
+void m_delete(int nargs);
+void m_status(int nargs);
+void m_error(int nargs);
+void m_readPICT(int nargs);
+void m_nativeFileName(int nargs);
+void m_hwnd(int nargs);
+
+} // End of namespace XWINXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 4d076902a2e..1e69e9b3902 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -110,6 +110,7 @@ MODULE_OBJS = \
lingo/xlibs/movutils.o \
lingo/xlibs/openbleedwindowxcmd.o \
lingo/xlibs/orthoplayxobj.o \
+ lingo/xlibs/paco.o \
lingo/xlibs/palxobj.o \
lingo/xlibs/panel.o \
lingo/xlibs/popupmenuxobj.o \
@@ -141,6 +142,7 @@ MODULE_OBJS = \
lingo/xlibs/xio.o \
lingo/xlibs/xplayanim.o \
lingo/xlibs/xsoundxfcn.o \
+ lingo/xlibs/xwin.o \
lingo/xlibs/yasix.o \
lingo/xtras/scrnutil.o
Commit: abba88197c1403e5995fe3cdf2bc59390731c008
https://github.com/scummvm/scummvm/commit/abba88197c1403e5995fe3cdf2bc59390731c008
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Fix start offset of wipe transitions
Changed paths:
engines/director/transitions.cpp
diff --git a/engines/director/transitions.cpp b/engines/director/transitions.cpp
index b5c7e69c7fe..261bed17832 100644
--- a/engines/director/transitions.cpp
+++ b/engines/director/transitions.cpp
@@ -239,13 +239,14 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
Graphics::ManagedSurface *blitFrom;
bool fullredraw = false;
+ debugC(2, kDebugImages, "Window::playTransition(): type: %d, duration: %d, area: %d, chunkSize: %d, steps: %d, stepDuration: %d, xpos: %d, ypos: %d, xStepSize: %d, yStepSize: %d, stripSize: %d, clipRect: %d %d %d %d", t.type, t.duration, t.area, t.chunkSize, t.steps, t.stepDuration, t.xpos, t.ypos, t.xStepSize, t.yStepSize, t.stripSize, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
+
switch (transProps[t.type].algo) {
case kTransAlgoDissolve:
if (t.type == kTransDissolvePatterns)
dissolvePatternsTrans(t, clipRect, &nextFrame);
else
dissolveTrans(t, clipRect, &nextFrame);
- debugC(2, kDebugImages, "Window::playTransition(): type: %d, duration: %d, area: %d, chunkSize: %d, steps: %d, stepDuration: %d, xpos: %d, ypos: %d, xStepSize: %d, yStepSize: %d, stripSize: %d", t.type, t.duration, t.area, t.chunkSize, t.steps, t.stepDuration, t.xpos, t.ypos, t.xStepSize, t.yStepSize, t.stripSize);
debugC(2, kDebugImages, "Window::playTransition(): Transition %d finished in %d ms", t.type, g_system->getMillis() - transStartTime);
return;
@@ -253,13 +254,11 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
case kTransAlgoStrips:
case kTransAlgoBlinds:
transMultiPass(t, clipRect, &nextFrame);
- debugC(2, kDebugImages, "Window::playTransition(): type: %d, duration: %d, area: %d, chunkSize: %d, steps: %d, stepDuration: %d, xpos: %d, ypos: %d, xStepSize: %d, yStepSize: %d, stripSize: %d", t.type, t.duration, t.area, t.chunkSize, t.steps, t.stepDuration, t.xpos, t.ypos, t.xStepSize, t.yStepSize, t.stripSize);
debugC(2, kDebugImages, "Window::playTransition(): Transition %d finished in %d ms", t.type, g_system->getMillis() - transStartTime);
return;
case kTransAlgoZoom:
transZoom(t, clipRect, ¤tFrame, &nextFrame);
- debugC(2, kDebugImages, "Window::playTransition(): type: %d, duration: %d, area: %d, chunkSize: %d, steps: %d, stepDuration: %d, xpos: %d, ypos: %d, xStepSize: %d, yStepSize: %d, stripSize: %d", t.type, t.duration, t.area, t.chunkSize, t.steps, t.stepDuration, t.xpos, t.ypos, t.xStepSize, t.yStepSize, t.stripSize);
debugC(2, kDebugImages, "Window::playTransition(): Transition %d finished in %d ms", t.type, g_system->getMillis() - transStartTime);
return;
@@ -297,24 +296,24 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
switch (t.type) {
case kTransWipeRight: // 1
- rto.setWidth(MAX((int16)0, (int16)(t.xStepSize * i)));
+ rto.setWidth(MAX((int16)0, (int16)(t.xpos + t.xStepSize * i)));
rfrom = rto;
break;
case kTransWipeLeft: // 2
- rto.setWidth(MAX((int16)0, (int16)(t.xStepSize * i)));
- rto.translate(w - t.xStepSize * i, 0);
+ rto.setWidth(MAX((int16)0, (int16)(t.xpos + t.xStepSize * i)));
+ rto.translate(w - t.xpos - t.xStepSize * i, 0);
rfrom = rto;
break;
case kTransWipeDown: // 3
- rto.setHeight(MAX((int16)0, (int16)(t.yStepSize * i)));
+ rto.setHeight(MAX((int16)0, (int16)(t.ypos + t.yStepSize * i)));
rfrom = rto;
break;
case kTransWipeUp: // 4
- rto.setHeight(MAX((int16)0, (int16)(t.yStepSize * i)));
- rto.translate(0, h - t.yStepSize * i);
+ rto.setHeight(MAX((int16)0, (int16)(t.ypos + t.yStepSize * i)));
+ rto.translate(0, h - t.ypos - t.yStepSize * i);
rfrom = rto;
break;
@@ -581,7 +580,6 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
g_lingo->executePerFrameHook(t.frame, i);
}
- debugC(2, kDebugImages, "Window::playTransition(): type: %d, duration: %d, area: %d, chunkSize: %d, steps: %d, stepDuration: %d, xpos: %d, ypos: %d, xStepSize: %d, yStepSize: %d, stripSize: %d", t.type, t.duration, t.area, t.chunkSize, t.steps, t.stepDuration, t.xpos, t.ypos, t.xStepSize, t.yStepSize, t.stripSize);
debugC(2, kDebugImages, "Window::playTransition(): Transition %d finished in %d ms", t.type, g_system->getMillis() - transStartTime);
}
Commit: 9d574a9e0e8ae40afe4c89bebb1b1646f92e9b66
https://github.com/scummvm/scummvm/commit/9d574a9e0e8ae40afe4c89bebb1b1646f92e9b66
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Add Paco video player for Hell Cab
Changed paths:
engines/director/lingo/xlibs/paco.cpp
video/paco_decoder.cpp
video/paco_decoder.h
diff --git a/engines/director/lingo/xlibs/paco.cpp b/engines/director/lingo/xlibs/paco.cpp
index 387b7262a0c..6fbfc7c7312 100644
--- a/engines/director/lingo/xlibs/paco.cpp
+++ b/engines/director/lingo/xlibs/paco.cpp
@@ -20,8 +20,12 @@
*/
#include "common/system.h"
+#include "common/tokenizer.h"
+#include "graphics/paletteman.h"
+#include "video/paco_decoder.h"
#include "director/director.h"
+#include "director/window.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-object.h"
#include "director/lingo/lingo-utils.h"
@@ -47,6 +51,7 @@ namespace Director {
const char *PACoXObj::xlibName = "PACo";
const char *PACoXObj::fileNames[] = {
"PACO",
+ "PACOW",
nullptr
};
@@ -78,9 +83,108 @@ void PACoXObj::close(ObjectType type) {
}
+void callPacoPlay(const Common::String &cmd) {
+ Common::StringTokenizer st(cmd);
+
+ Common::String verb = st.nextToken();
+ if (verb == "playfile") {
+
+ Common::String videoPath = st.nextToken();
+
+ int posX = 0;
+ int posY = 0;
+
+ while (!st.empty()) {
+ Common::String token = st.nextToken();
+ if (token == "-posx") {
+ posX = atoi(st.nextToken().c_str());
+ } else if (token == "-posy") {
+ posY = atoi(st.nextToken().c_str());
+ } else {
+ warning("callPacoPlay: Unknown parameter %s %s", token.c_str(), st.nextToken().c_str());
+ }
+ }
+
+ Video::PacoDecoder *video = new Video::PacoDecoder();
+ bool result = video->loadFile(findPath(videoPath));
+ if (!result) {
+ warning("callPacoPlay: PACo video not loaded: %s", videoPath.c_str());
+ delete video;
+ return;
+ }
+
+ // 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_system->getEventManager()->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);
+ }
+
+ video->close();
+ delete video;
+ } else {
+ warning("callPacoPlay: Unknown verb %s", verb.c_str());
+ }
+
+
+}
+
void PACoXObj::m_new(int nargs) {
g_lingo->printSTUBWithArglist("PACoXObj::m_new", nargs);
- g_lingo->dropStack(nargs);
+ if (nargs == 1) {
+ Common::String cmd = g_lingo->pop().asString();
+ callPacoPlay(cmd);
+ } else {
+ warning("PACoXObj::m_new: Invalid number of args %d", nargs);
+ g_lingo->dropStack(nargs);
+ }
g_lingo->push(g_lingo->_state->me);
}
diff --git a/video/paco_decoder.cpp b/video/paco_decoder.cpp
index 4e40e1ee5e8..f0f88497a43 100644
--- a/video/paco_decoder.cpp
+++ b/video/paco_decoder.cpp
@@ -77,6 +77,10 @@ bool PacoDecoder::loadStream(Common::SeekableReadStream *stream) {
uint16 height = stream->readUint16BE();
int16 frameRate = stream->readUint16BE();
frameRate = ABS(frameRate); // Negative framerate is indicative of audio, but not always
+ if (frameRate == 0) {
+ // 0 is equivalent to playing back at the fastest rate
+ frameRate = 60;
+ }
uint16 flags = stream->readUint16BE();
bool hasAudio = (flags & 0x100) == 0x100;
@@ -204,6 +208,9 @@ Graphics::PixelFormat PacoDecoder::PacoVideoTrack::getPixelFormat() const {
}
void PacoDecoder::readNextPacket() {
+ if (_curFrame >= _videoTrack->getFrameCount())
+ return;
+
uint32 nextFrame = _fileStream->pos() + _frameSizes[_curFrame];
debug(2, " frame %3d size %d @ %lX", _curFrame, _frameSizes[_curFrame], long(_fileStream->pos()));
@@ -228,6 +235,9 @@ void PacoDecoder::readNextPacket() {
_videoTrack->handlePalette(_fileStream);
break;
case EOC:
+ _videoTrack->handleEOC();
+ break;
+ case NOP:
break;
default:
error("PacoDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType);
diff --git a/video/paco_decoder.h b/video/paco_decoder.h
index 67cff6d0d7a..0a83599b2c9 100644
--- a/video/paco_decoder.h
+++ b/video/paco_decoder.h
@@ -76,6 +76,7 @@ protected:
int getFrameCount() const override { return _frameCount; }
virtual const Graphics::Surface *decodeNextFrame() override;
virtual void handleFrame(Common::SeekableReadStream *fileStream, uint32 chunkSize, int curFrame);
+ virtual void handleEOC() { _curFrame += 1; };
void handlePalette(Common::SeekableReadStream *fileStream);
const byte *getPalette() const override;
bool hasDirtyPalette() const override { return _dirtyPalette; }
Commit: 461f39508ab19f6d91ffcc79ed16b9d78e779f1b
https://github.com/scummvm/scummvm/commit/461f39508ab19f6d91ffcc79ed16b9d78e779f1b
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Sort output of the "vars" debugger command
Changed paths:
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index f8f69110e14..9507c45c0f9 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1528,11 +1528,19 @@ void Lingo::cleanLocalVars() {
Common::String Lingo::formatAllVars() {
Common::String result;
+ Common::Array<Common::String> keyBuffer;
+
result += Common::String(" Local vars:\n");
if (_state->localVars) {
- for (auto &i : *_state->localVars) {
- result += Common::String::format(" %s - [%s] %s\n", i._key.c_str(), i._value.type2str(), i._value.asString(true).c_str());
+ for (auto &it : *_state->localVars) {
+ keyBuffer.push_back(it._key);
+ }
+ Common::sort(keyBuffer.begin(), keyBuffer.end());
+ for (auto &i : keyBuffer) {
+ Datum &val = _state->localVars->getVal(i);
+ result += Common::String::format(" %s - [%s] %s\n", i.c_str(), val.type2str(), formatStringForDump(val.asString(true)).c_str());
}
+ keyBuffer.clear();
} else {
result += Common::String(" (no local vars)\n");
}
@@ -1541,16 +1549,28 @@ Common::String Lingo::formatAllVars() {
if (_state->me.type == OBJECT && _state->me.u.obj->getObjType() & (kFactoryObj | kScriptObj)) {
ScriptContext *script = static_cast<ScriptContext *>(_state->me.u.obj);
result += Common::String(" Instance/property vars: \n");
- for (auto &i : script->_properties) {
- result += Common::String::format(" %s - [%s] %s\n", i._key.c_str(), i._value.type2str(), i._value.asString(true).c_str());
+ for (auto &it : script->_properties) {
+ keyBuffer.push_back(it._key);
}
+ Common::sort(keyBuffer.begin(), keyBuffer.end());
+ for (auto &i : keyBuffer) {
+ Datum &val = script->_properties.getVal(i);
+ result += Common::String::format(" %s - [%s] %s\n", i.c_str(), val.type2str(), formatStringForDump(val.asString(true)).c_str());
+ }
+ keyBuffer.clear();
result += Common::String("\n");
}
result += Common::String(" Global vars:\n");
- for (auto &i : _globalvars) {
- result += Common::String::format(" %s - [%s] %s\n", i._key.c_str(), i._value.type2str(), i._value.asString(true).c_str());
+ for (auto &it : _globalvars) {
+ keyBuffer.push_back(it._key);
+ }
+ Common::sort(keyBuffer.begin(), keyBuffer.end());
+ for (auto &i : keyBuffer) {
+ Datum &val = _globalvars.getVal(i);
+ result += Common::String::format(" %s - [%s] %s\n", i.c_str(), val.type2str(), formatStringForDump(val.asString(true)).c_str());
}
+ keyBuffer.clear();
result += Common::String("\n");
return result;
}
Commit: df1dbd33beb215b77765640dd76f5b51fe95959c
https://github.com/scummvm/scummvm/commit/df1dbd33beb215b77765640dd76f5b51fe95959c
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Always resize bitmap Sprite when setting cast member
Fixes body part drawers in Gahan Wilson's The Ultimate Haunted
House.
Fixes inventory screen frame in Hell Cab.
Changed paths:
engines/director/sprite.cpp
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index e0f555c63a6..28608fa7023 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -111,7 +111,7 @@ Sprite& Sprite::operator=(const Sprite &sprite) {
_foreColor = sprite._foreColor;
_blend = sprite._blend;
-
+
_volume = sprite._volume;
_stretch = sprite._stretch;
@@ -455,22 +455,11 @@ void Sprite::setCast(CastMemberID memberID) {
}
}
- // TODO: Respect sprite width/height settings. Need to determine how to read
- // them properly.
Common::Rect dims = _cast->getInitialRect();
- // strange logic here, need to be fixed
switch (_cast->_type) {
case kCastBitmap:
- // for the stretched sprites, we need the original size to get the correct bbox offset.
- // there are two stretch situation here.
- // 1. stretch happened when creating the widget, there is no lingo participated. we will use the original sprite size to create widget. check copyStretchImg
- // 2. stretch set by lingo. this time we need to store the original dims because we will create the original sprite and stretch it when bliting. check inkBlitStretchSurface
- {
- if (!(_inkData & 0x80) || _stretch) {
- _width = dims.width();
- _height = dims.height();
- }
- }
+ _width = dims.width();
+ _height = dims.height();
break;
case kCastShape:
case kCastText: // fall-through
Commit: ea089282c7eb5263c834145de840f9caee8e9f74
https://github.com/scummvm/scummvm/commit/ea089282c7eb5263c834145de840f9caee8e9f74
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Set the _stretch Sprite flag when loading frames
Flag _inkData & 0x80 is set by Director when a Score sprite has been
stretched. Confirmed that "the stretch of sprite" is expected to reflect
this.
Changed paths:
engines/director/frame.cpp
engines/director/score.cpp
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 3b376eba6ea..e3e9d87b6cc 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -331,10 +331,8 @@ void readSpriteDataD2(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
sprite._inkData = stream.readByte();
sprite._ink = static_cast<InkType>(sprite._inkData & 0x3f);
- if (sprite._inkData & 0x40)
- sprite._trails = 1;
- else
- sprite._trails = 0;
+ sprite._trails = sprite._inkData & 0x40 ? 1 : 0;
+ sprite._stretch = sprite._inkData & 0x80 ? 1 : 0;
}
break;
case 6:
@@ -641,10 +639,8 @@ void readSpriteDataD4(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
sprite._inkData = stream.readByte();
sprite._ink = static_cast<InkType>(sprite._inkData & 0x3f);
- if (sprite._inkData & 0x40)
- sprite._trails = 1;
- else
- sprite._trails = 0;
+ sprite._trails = sprite._inkData & 0x40 ? 1 : 0;
+ sprite._stretch = sprite._inkData & 0x80 ? 1 : 0;
}
break;
case 6:
@@ -927,10 +923,8 @@ void readSpriteDataD5(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
sprite._inkData = stream.readByte();
sprite._ink = static_cast<InkType>(sprite._inkData & 0x3f);
- if (sprite._inkData & 0x40)
- sprite._trails = 1;
- else
- sprite._trails = 0;
+ sprite._trails = sprite._inkData & 0x40 ? 1 : 0;
+ sprite._stretch = sprite._inkData & 0x80 ? 1 : 0;
}
break;
case 2:
@@ -1131,10 +1125,8 @@ void readSpriteDataD6(Common::SeekableReadStreamEndian &stream, Sprite &sprite,
sprite._inkData = inkData;
sprite._ink = static_cast<InkType>(sprite._inkData & 0x3f);
- if (sprite._inkData & 0x40)
- sprite._trails = 1;
- else
- sprite._trails = 0;
+ sprite._trails = sprite._inkData & 0x40 ? 1 : 0;
+ sprite._stretch = sprite._inkData & 0x80 ? 1 : 0;
}
break;
case 2: {
@@ -1268,9 +1260,9 @@ Common::String Frame::formatChannelInfo() {
for (int i = 0; i < _numChannels; i++) {
Sprite &sprite = *_sprites[i + 1];
if (sprite._castId.member) {
- result += Common::String::format("CH: %-3d castId: %s, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, blend: 0x%x, unk3: 0x%x\n",
+ result += Common::String::format("CH: %-3d castId: %s, [inkData: 0x%02x [ink: %d, trails: %d, stretch: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, blend: 0x%x, unk3: 0x%x\n",
i + 1, sprite._castId.asString().c_str(), sprite._inkData,
- sprite._ink, sprite._trails, sprite._thickness, sprite._width, sprite._height,
+ sprite._ink, sprite._trails, sprite._stretch, sprite._thickness, sprite._width, sprite._height,
sprite._startPoint.x, sprite._startPoint.y,
sprite._spriteType, spriteType2str(sprite._spriteType), sprite._foreColor,
sprite._backColor, sprite._scriptId.asString().c_str(), sprite._colorcode,
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 1f84567d8aa..3a597c88201 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1815,13 +1815,13 @@ Common::String Score::formatChannelInfo() {
Channel &channel = *_channels[i + 1];
Sprite &sprite = *channel._sprite;
if (sprite._castId.member) {
- result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, stretch: %d, moveable: %d\n",
+ result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, stretch: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, moveable: %d\n",
i + 1, sprite._castId.asString().c_str(), channel._visible, sprite._inkData,
- sprite._ink, sprite._trails, sprite._thickness, channel._width, channel._height,
+ sprite._ink, sprite._trails, sprite._stretch, sprite._thickness, channel._width, channel._height,
channel._currentPoint.x, channel._currentPoint.y,
sprite._spriteType, spriteType2str(sprite._spriteType), sprite._foreColor, sprite._backColor,
sprite._scriptId.asString().c_str(), sprite._colorcode, sprite._blendAmount, sprite._unk3,
- channel._constraint, sprite._puppet, sprite._stretch, sprite._moveable);
+ channel._constraint, sprite._puppet, sprite._moveable);
} else {
result += Common::String::format("CH: %-3d castId: 000\n", i + 1);
}
Commit: eb5b867b3600d1fe4fc8b03830ec2017d2dfe563
https://github.com/scummvm/scummvm/commit/eb5b867b3600d1fe4fc8b03830ec2017d2dfe563
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Refactor Channel::getBbox
The behaviour in real Director is to allow width/height/position
changes in Lingo, but only apply them when the Sprite puppet flag is
set.
Changed paths:
engines/director/channel.cpp
engines/director/channel.h
engines/director/sprite.h
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 021d82d9640..3d07b1c0d4d 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -230,7 +230,7 @@ bool Channel::isDirty(Sprite *nextSprite) {
_sprite->_foreColor != nextSprite->_foreColor;
if (!_sprite->_moveable)
isDirtyFlag |= _currentPoint != nextSprite->_startPoint;
- if (!_sprite->_stretch && !hasTextCastMember(_sprite))
+ if (isStretched() && !hasTextCastMember(_sprite))
isDirtyFlag |= _width != nextSprite->_width || _height != nextSprite->_height;
}
@@ -238,8 +238,8 @@ bool Channel::isDirty(Sprite *nextSprite) {
}
bool Channel::isStretched() {
- return _sprite->_puppet && _sprite->_stretch &&
- (_sprite->_width != _width || _sprite->_height != _height);
+ return _sprite->_stretch || (_sprite->_puppet &&
+ (_sprite->_width != _width || _sprite->_height != _height));
}
bool Channel::isEmpty() {
@@ -355,12 +355,31 @@ bool Channel::isVideoDirectToStage() {
}
Common::Rect Channel::getBbox(bool unstretched) {
- Common::Rect result(unstretched ? _sprite->_width : _width,
- unstretched ? _sprite->_height : _height);
- if (_sprite->_cast) {
- result = _sprite->_cast->getBbox(_width, _height);
- }
- result.translate(_currentPoint.x, _currentPoint.y);
+ bool isShape = _sprite->_cast && _sprite->_cast->_type == kCastShape;
+ // Use the dimensions and position in the Channel:
+ // - if the sprite is of a shape, or
+ // - if the sprite has the puppet flag enabled
+ // Otherwise, use the Sprite dimensions and position (i.e. taken from the
+ // frame data in the Score).
+ // Setting unstretched to true always returns the Sprite dimensions.
+ bool useOverride = (isShape || _sprite->_puppet) && !unstretched;
+
+ Common::Rect result(
+ useOverride ? _width : _sprite->_width,
+ useOverride ? _height : _sprite->_height
+ );
+ // If this is a cast member, use the cast member's getBbox function
+ // so we start with a rect containing the correct registration offset.
+ if (_sprite->_cast)
+ result = _sprite->_cast->getBbox(result.width(), result.height());
+
+ // The origin of the rect should be at the registration offset,
+ // e.g. for bitmap sprites this defaults to the centre.
+ // Now we move the rect to the correct spot.
+ result.translate(
+ useOverride ? _currentPoint.x : _sprite->_startPoint.x,
+ useOverride ? _currentPoint.y : _sprite->_startPoint.y
+ );
return result;
}
@@ -389,7 +408,7 @@ void Channel::setClean(Sprite *nextSprite, bool partial) {
// if cast are modified, then we need to replace it
// if cast size are changed, and we may need to replace it, because we may having the scaled bitmap castmember
// other situation, e.g. position changing, we will let channel to handle it. So we don't have to replace widget
- bool dimsChanged = !_sprite->_stretch && !hasTextCastMember(_sprite) && (_sprite->_width != nextSprite->_width || _sprite->_height != nextSprite->_height);
+ bool dimsChanged = !isStretched() && !hasTextCastMember(_sprite) && (_sprite->_width != nextSprite->_width || _sprite->_height != nextSprite->_height);
// if spriteType is changing, then we may need to re-create the widget since spriteType will guide when we creating widget
bool spriteTypeChanged = _sprite->_spriteType != nextSprite->_spriteType;
@@ -562,15 +581,11 @@ void Channel::replaceSprite(Sprite *nextSprite) {
if (!_sprite->_moveable || newSprite)
_currentPoint = _sprite->_startPoint;
- if (!_sprite->_stretch) {
- _width = _sprite->_width;
- _height = _sprite->_height;
- }
+ _width = _sprite->_width;
+ _height = _sprite->_height;
}
void Channel::setWidth(int w) {
- if (!(_sprite->_stretch || (_sprite->_cast && _sprite->_cast->_type == kCastShape)))
- return;
_width = MAX<int>(w, 0);
// Based on Director in a Nutshell, page 15
@@ -578,8 +593,6 @@ void Channel::setWidth(int w) {
}
void Channel::setHeight(int h) {
- if (!(_sprite->_stretch || (_sprite->_cast && _sprite->_cast->_type == kCastShape)))
- return;
_height = MAX<int>(h, 0);
// Based on Director in a Nutshell, page 15
@@ -587,8 +600,6 @@ void Channel::setHeight(int h) {
}
void Channel::setBbox(int l, int t, int r, int b) {
- if (!(_sprite->_stretch || (_sprite->_cast && _sprite->_cast->_type == kCastShape)))
- return;
_width = r - l;
_height = b - t;
diff --git a/engines/director/channel.h b/engines/director/channel.h
index ace25307bf8..758ba5cf122 100644
--- a/engines/director/channel.h
+++ b/engines/director/channel.h
@@ -45,6 +45,7 @@ public:
DirectorPlotData getPlotData();
const Graphics::Surface *getMask(bool forceMatte = false);
+ // Return the area of screen to be used for drawing content.
Common::Rect getBbox(bool unstretched = false);
bool isStretched();
@@ -96,10 +97,18 @@ public:
bool _dirty;
bool _visible;
uint _constraint;
- Common::Point _currentPoint;
Graphics::ManagedSurface *_mask;
int _priority;
+
+ // These fields are used for tracking overrides for the position, width and height of
+ // the channel, as available in Lingo.
+ // Basically, if the sprite -isn't- in puppet mode, Lingo will allow you to set
+ // these values to whatever, but the sprite on the screen will still be the position and
+ // dimensions from the score frame.
+ // If you set puppet mode, the sprite on the screen will use these values instead.
+ // If you set puppet mode, change things, then disable puppet mode, it will revert to the score.
+ Common::Point _currentPoint;
int _width;
int _height;
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 32183f9d92a..549c44ef62d 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -105,9 +105,14 @@ public:
CastMember *_cast;
byte _thickness;
+
+ // These fields are used for tracking the position, width and height of the sprite,
+ // as received from the score frame data.
+ // Don't change these; instead adjust the equivalent properties in Channel.
Common::Point _startPoint;
int16 _width;
int16 _height;
+
bool _moveable;
bool _editable;
bool _puppet;
@@ -117,7 +122,7 @@ public:
uint32 _foreColor;
byte _blend;
-
+
byte _volume;
byte _stretch;
};
Commit: 4a552fd61cf1f87371aaeb526b36c248be72f8b7
https://github.com/scummvm/scummvm/commit/4a552fd61cf1f87371aaeb526b36c248be72f8b7
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Add Mean City to detection table
Changed paths:
engines/director/detection_tables.h
diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index 967f34df166..e182c675013 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -294,6 +294,7 @@ static const PlainGameDescriptor directorGames[] = {
{ "mckenziemf", "McKenzie & Co.: More Friends" }, // Expansion for McKenzie & Co.
{ "mcluhan", "Understanding McLuhan" },
{ "mcmillennium", "Mission Code: Millennium" },
+ { "meancity", "Mean City: Learn English or Die!" },
{ "mediaband", "Meet MediaBand" },
{ "meetchuck", "Meet Chuck" },
{ "melements", "Masters of the Elements" },
@@ -7594,6 +7595,8 @@ static const DirectorGameDescription gameDescriptions[] = {
WINGAME1t("mcdonaldland", "", "McLand.exe", "f15f57b8b90986d6b34f8bf3a5487dfb", 1501901, 602),
+ WINGAME1("meancity", "", "mc32.exe", "t:746d26c4e79cf5c81f8aaf09709d8488", 1527265, 602),
+
// Masters of the Elements - English and German (from lotharsm)
// Original Dutch game Meesters van Macht released in 1997
// Released in Germany as "Meister Zufall und die Herrscher der Elemente"
Commit: f92f78ef9a14237766c0ea60c33e81c81789466d
https://github.com/scummvm/scummvm/commit/f92f78ef9a14237766c0ea60c33e81c81789466d
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Fix Sprite::checkSpriteType for film loops
Changed paths:
engines/director/sprite.cpp
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 28608fa7023..e62afec8e00 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -411,7 +411,7 @@ bool Sprite::checkSpriteType() {
// check whether the sprite type match the cast type
// if it doesn't match, then we treat it as transparent
// this happens in warlock-mac data/stambul/c up
- if (_spriteType == kBitmapSprite && _cast->_type != kCastBitmap) {
+ if (_spriteType == kBitmapSprite && !(_cast->_type == kCastBitmap || _cast->_type == kCastFilmLoop)) {
if (debugChannelSet(4, kDebugImages))
warning("Sprite::checkSpriteType: Didn't render sprite due to the sprite type mismatch with cast type");
return false;
Commit: fa2e5ac9deaa19c45a7d184429a7863815516405
https://github.com/scummvm/scummvm/commit/fa2e5ac9deaa19c45a7d184429a7863815516405
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Fix FilmLoopCastMember::getSubChannels
The new bounding box calculation requires the transformed position/size
to be in Sprite, not Channel.
Fixes the visibility of the boar hunt in Wrath of the Gods.
Changed paths:
engines/director/castmember/filmloop.cpp
engines/director/window.cpp
diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index 828d5636cd7..c771a63ef5c 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -91,14 +91,17 @@ Common::Array<Channel> *FilmLoopCastMember::getSubChannels(Common::Rect &bbox, C
int16 width = src._width * widgetRect.width() / _initialRect.width();
int16 height = src._height * widgetRect.height() / _initialRect.height();
+ // Re-inject the translated position into the Sprite.
+ // This saves the hassle of having to force the Channel to be in puppet mode.
+ src._width = width;
+ src._height = height;
+ src._startPoint = Common::Point(absX, absY);
+ src._stretch = true;
+
// Film loop frames are constructed as a series of Channels, much like how a normal frame
// is rendered by the Score. We don't include a pointer to the current Score here,
// that's only for querying the constraint channel which is not used.
Channel chan(nullptr, &src);
- chan._currentPoint = Common::Point(absX, absY);
- chan._width = width;
- chan._height = height;
-
_subchannels.push_back(chan);
}
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index a21e27207b9..36e9d2e079e 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -302,7 +302,11 @@ void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Mana
uint32 renderStartTime = 0;
if (debugChannelSet(8, kDebugImages)) {
CastType castType = channel->_sprite->_cast ? channel->_sprite->_cast->_type : kCastTypeNull;
- debugC(8, kDebugImages, "Window::inkBlitFrom(): updating %dx%d @ %d,%d, type: %s, ink: %d", destRect.width(), destRect.height(), destRect.left, destRect.top, castType2str(castType), channel->_sprite->_ink);
+ debugC(8, kDebugImages, "Window::inkBlitFrom(): updating %dx%d @ %d,%d -> %dx%d @ %d,%d, type: %s, cast: %s, ink: %d",
+ srcRect.width(), srcRect.height(), srcRect.left, srcRect.top,
+ destRect.width(), destRect.height(), destRect.left, destRect.top,
+ castType2str(castType), channel->_sprite->_castId.asString().c_str(),
+ channel->_sprite->_ink);
renderStartTime = g_system->getMillis();
}
Commit: 8ebfb3a2eafad37f659ec8374e70d09cde96a014
https://github.com/scummvm/scummvm/commit/8ebfb3a2eafad37f659ec8374e70d09cde96a014
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Fix digital video playback state leak
Playing two digital videos back to back in the same channel was not
working; both videos thought they controlled the channel, which meant
that the first video would complete, then set _movieRate in the channel
to 0, which would then be misinterpreted by e.g.
Score::isWaitingForNextFrame() as a sign that the second video had
finished.
Fixes the introductory videos in Eastern Mind.
Fixes the conversation with the two ladies at the river in Wrath of the
Gods.
Changed paths:
engines/director/castmember/digitalvideo.cpp
engines/director/castmember/digitalvideo.h
engines/director/channel.cpp
engines/director/lingo/lingo-the.cpp
engines/director/score.cpp
diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index 1790ff1e97c..f68280e175a 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -147,7 +147,7 @@ bool DigitalVideoCastMember::isModified() {
if (_video->endOfVideo()) {
if (_looping) {
_video->rewind();
- } else {
+ } else if (_channel) {
_channel->_movieRate = 0.0;
}
}
@@ -155,15 +155,13 @@ bool DigitalVideoCastMember::isModified() {
if (_getFirstFrame)
return true;
- if (_channel->_movieRate == 0.0)
+ if (_channel && _channel->_movieRate == 0.0)
return false;
return _video->needsUpdate();
}
-void DigitalVideoCastMember::startVideo(Channel *channel) {
- _channel = channel;
-
+void DigitalVideoCastMember::startVideo() {
if (!_video || !_video->isVideoLoaded()) {
warning("DigitalVideoCastMember::startVideo: No video %s", !_video ? "decoder" : "loaded");
return;
@@ -172,7 +170,7 @@ void DigitalVideoCastMember::startVideo(Channel *channel) {
if (_pausedAtStart) {
_getFirstFrame = true;
} else {
- if (_channel->_movieRate == 0.0)
+ if (_channel && _channel->_movieRate == 0.0)
_channel->_movieRate = 1.0;
}
@@ -183,7 +181,7 @@ void DigitalVideoCastMember::startVideo(Channel *channel) {
debugC(2, kDebugImages, "STARTING VIDEO %s", _filename.c_str());
- if (_channel->_stopTime == 0)
+ if (_channel && _channel->_stopTime == 0)
_channel->_stopTime = getMovieTotalTime();
_duration = getMovieTotalTime();
diff --git a/engines/director/castmember/digitalvideo.h b/engines/director/castmember/digitalvideo.h
index 8c1d6cab11a..9073e87fefd 100644
--- a/engines/director/castmember/digitalvideo.h
+++ b/engines/director/castmember/digitalvideo.h
@@ -40,7 +40,8 @@ public:
bool loadVideoFromCast();
bool loadVideo(Common::String path);
- void startVideo(Channel *channel);
+ void setChannel(Channel *channel) { _channel = channel; }
+ void startVideo();
void stopVideo();
void rewindVideo();
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 3d07b1c0d4d..207eb8486fb 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -418,7 +418,8 @@ void Channel::setClean(Sprite *nextSprite, bool partial) {
if (_sprite->_castId != nextSprite->_castId && nextSprite->_cast->_type == kCastDigitalVideo) {
if (((DigitalVideoCastMember *)nextSprite->_cast)->loadVideoFromCast()) {
_movieTime = 0;
- ((DigitalVideoCastMember *)nextSprite->_cast)->startVideo(this);
+ ((DigitalVideoCastMember *)nextSprite->_cast)->setChannel(this);
+ ((DigitalVideoCastMember *)nextSprite->_cast)->startVideo();
}
} else if (nextSprite->_cast->_type == kCastFilmLoop) {
// brand new film loop, reset the frame counter
@@ -539,6 +540,13 @@ void Channel::replaceSprite(Sprite *nextSprite) {
bool newSprite = (_sprite->_spriteType == kInactiveSprite && nextSprite->_spriteType != kInactiveSprite);
bool widgetKeeped = _sprite->_cast && _widget;
+ // if there's a video in the old sprite that's different, stop it before we continue
+ if (_sprite->_castId != nextSprite->_castId && _sprite->_cast && _sprite->_cast->_type == kCastDigitalVideo) {
+ ((DigitalVideoCastMember *)_sprite->_cast)->setChannel(nullptr);
+ ((DigitalVideoCastMember *)_sprite->_cast)->stopVideo();
+ ((DigitalVideoCastMember *)_sprite->_cast)->rewindVideo();
+ }
+
// update the _sprite we stored in channel, and point the originalSprite to the new one
// release the widget, because we may having the new one
if (_sprite->_cast && !canKeepWidget(_sprite, nextSprite)) {
@@ -546,10 +554,6 @@ void Channel::replaceSprite(Sprite *nextSprite) {
_sprite->_cast->releaseWidget();
newSprite = true;
}
- if (_sprite->_castId != nextSprite->_castId && _sprite->_cast && _sprite->_cast->_type == kCastDigitalVideo) {
- ((DigitalVideoCastMember *)_sprite->_cast)->stopVideo();
- ((DigitalVideoCastMember *)_sprite->_cast)->rewindVideo();
- }
// If the cast member is the same, persist the editable flag
bool editable = nextSprite->_editable;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index c49f0b365fb..1244d01ed9e 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1483,7 +1483,8 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
if (castMember && castMember->_type == kCastDigitalVideo) {
if (((DigitalVideoCastMember *)castMember)->loadVideoFromCast()) {
- ((DigitalVideoCastMember *)castMember)->startVideo(channel);
+ ((DigitalVideoCastMember *)castMember)->setChannel(channel);
+ ((DigitalVideoCastMember *)castMember)->startVideo();
// b_updateStage needs to have _videoPlayback set to render video
// in the regular case Score::renderSprites sets it.
// However Score::renderSprites is not in the current code path.
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 3a597c88201..b2a1d127a14 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -337,8 +337,8 @@ void Score::setDelay(uint32 ticks) {
bool Score::isWaitingForNextFrame() {
bool keepWaiting = false;
+ debugC(8, kDebugLoading, "Score::isWaitingForNextFrame(): nextFrameTime: %d, time: %d, sound: %d, click: %d, video: %d", _nextFrameTime, g_system->getMillis(false), _waitForChannel, _waitForClick, _waitForVideoChannel);
- debugC(8, kDebugLoading, "Score::isWaitingForNextFrame(): nextFrameTime: %d, time: %d", _nextFrameTime, g_system->getMillis(false));
if (_waitForChannel) {
if (_soundManager->isChannelActive(_waitForChannel)) {
keepWaiting = true;
@@ -363,6 +363,9 @@ bool Score::isWaitingForNextFrame() {
keepWaiting = true;
}
+ if (!keepWaiting) {
+ debugC(8, kDebugLoading, "Score::isWaitingForNextFrame(): end of wait cycle");
+ }
return keepWaiting;
}
Commit: bf3947c19aec1c05d51e66401f3b1ee65738aebc
https://github.com/scummvm/scummvm/commit/bf3947c19aec1c05d51e66401f3b1ee65738aebc
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Fix loading of 1-bit images with DIBDecoder
Fixes loading the contract text bitmap in Hell Cab.
Changed paths:
engines/director/images.cpp
engines/director/images.h
diff --git a/engines/director/images.cpp b/engines/director/images.cpp
index 8206274a362..e45e61d3aad 100644
--- a/engines/director/images.cpp
+++ b/engines/director/images.cpp
@@ -33,6 +33,7 @@ DIBDecoder::DIBDecoder() {
_surface = nullptr;
_palette = nullptr;
_paletteColorCount = 0;
+ _bitsPerPixel = 0;
_codec = nullptr;
}
@@ -71,6 +72,7 @@ void DIBDecoder::loadPalette(Common::SeekableReadStream &stream) {
}
bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) {
+ //stream.hexdump(stream.size());
uint32 headerSize = stream.readUint32LE();
if (headerSize != 40)
return false;
@@ -81,7 +83,7 @@ bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) {
warning("BUILDBOT: height < 0 for DIB");
}
stream.readUint16LE(); // planes
- uint16 bitsPerPixel = stream.readUint16LE();
+ _bitsPerPixel = stream.readUint16LE();
uint32 compression = stream.readUint32BE();
/* uint32 imageSize = */ stream.readUint32LE();
/* int32 pixelsPerMeterX = */ stream.readSint32LE();
@@ -93,15 +95,25 @@ bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) {
Common::SeekableSubReadStream subStream(&stream, 40, stream.size());
- _codec = Image::createBitmapCodec(compression, 0, width, height, bitsPerPixel);
+ _codec = Image::createBitmapCodec(compression, 0, width, height, _bitsPerPixel);
if (!_codec)
return false;
_surface = _codec->decodeFrame(subStream);
+ // The DIB decoder converts 1bpp images to the 16-color equivalent; we need them to be the palette extrema
+ // in order to work.
+ if (_bitsPerPixel == 1) {
+ for (int y = 0; y < _surface->h; y++) {
+ for (int x = 0; x < _surface->w; x++) {
+ *const_cast<byte *>((const byte *)_surface->getBasePtr(x, y)) = *(const byte *)_surface->getBasePtr(x, y) == 0xf ? 0x00 : 0xff;
+ }
+ }
+ }
+
// For some reason, DIB cast members have the palette indexes reversed
- if (bitsPerPixel == 8) {
+ if (_bitsPerPixel == 8) {
for (int y = 0; y < _surface->h; y++) {
for (int x = 0; x < _surface->w; x++) {
// We're not su[pposed to modify the image that is coming from the decoder
diff --git a/engines/director/images.h b/engines/director/images.h
index f293fa4d2c2..b64ba8caa25 100644
--- a/engines/director/images.h
+++ b/engines/director/images.h
@@ -56,7 +56,8 @@ private:
Image::Codec *_codec;
const Graphics::Surface *_surface;
byte *_palette;
- uint8 _paletteColorCount;
+ uint32 _paletteColorCount;
+ uint16 _bitsPerPixel;
};
class BITDDecoder : public Image::ImageDecoder {
Commit: 1d44f6892bf1106fc2d1a06a39a5726bd7ba2066
https://github.com/scummvm/scummvm/commit/1d44f6892bf1106fc2d1a06a39a5726bd7ba2066
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
VIDEO: PACo decoder: Add bounds and null checks
Fixes playback of various videos in Hell Cab.
Changed paths:
video/paco_decoder.cpp
diff --git a/video/paco_decoder.cpp b/video/paco_decoder.cpp
index f0f88497a43..e4c70e93790 100644
--- a/video/paco_decoder.cpp
+++ b/video/paco_decoder.cpp
@@ -115,11 +115,11 @@ int PacoDecoder::getAudioSamplingRate() {
* Search for the first audio packet and use it.
*/
const Common::Array<int> samplingRates = {5563, 7418, 11127, 22254};
- int index;
+ int index = 0;
int64 startPos = _fileStream->pos();
- while (true){
+ while (_fileStream->pos() < _fileStream->size()) {
int64 currentPos = _fileStream->pos();
int frameType = _fileStream->readByte();
int v = _fileStream->readByte();
@@ -226,16 +226,20 @@ void PacoDecoder::readNextPacket() {
switch (frameType) {
case AUDIO:
- _audioTrack->queueSound(_fileStream, chunkSize - 4);
+ if (_audioTrack)
+ _audioTrack->queueSound(_fileStream, chunkSize - 4);
break;
case VIDEO:
- _videoTrack->handleFrame(_fileStream, chunkSize - 4, _curFrame);
+ if (_videoTrack)
+ _videoTrack->handleFrame(_fileStream, chunkSize - 4, _curFrame);
break;
case PALLETE:
- _videoTrack->handlePalette(_fileStream);
+ if (_videoTrack)
+ _videoTrack->handlePalette(_fileStream);
break;
case EOC:
- _videoTrack->handleEOC();
+ if (_videoTrack)
+ _videoTrack->handleEOC();
break;
case NOP:
break;
Commit: c49c10e881b80c1e2c65bc312234e75870e710f5
https://github.com/scummvm/scummvm/commit/c49c10e881b80c1e2c65bc312234e75870e710f5
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Enable kLPPTrimGarbage for D2/D3 scripts
With D2/D3 action and movie scripts, if there is a syntax error,
the compiler seems to truncate the script at the first unreadable
character, then attempt to compile again.
Fixes the machine gun minigame in Hell Cab.
Changed paths:
engines/director/cast.cpp
engines/director/movie.cpp
engines/director/score.cpp
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index d2041e7d670..a0a35cbe753 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -25,6 +25,7 @@
#include "common/memstream.h"
#include "common/substream.h"
+#include "director/types.h"
#include "graphics/macgui/macfontmanager.h"
#include "graphics/macgui/macwindowmanager.h"
@@ -1155,7 +1156,7 @@ void Cast::loadScriptV2(Common::SeekableReadStreamEndian &stream, uint16 id) {
if (ConfMan.getBool("dump_scripts"))
dumpScript(script.c_str(), kMovieScript, id);
- _lingoArchive->addCode(script.decode(Common::kMacRoman), kMovieScript, id, nullptr, kLPPForceD2);
+ _lingoArchive->addCode(script.decode(Common::kMacRoman), kMovieScript, id, nullptr, kLPPForceD2|kLPPTrimGarbage);
}
void Cast::dumpScript(const char *script, ScriptType type, uint16 id) {
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 6dfea889736..af5b8703532 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -324,7 +324,7 @@ void Movie::loadFileInfo(Common::SeekableReadStreamEndian &stream) {
_cast->dumpScript(_script.c_str(), kMovieScript, 0);
if (!_script.empty())
- _cast->_lingoArchive->addCode(_script, kMovieScript, 0);
+ _cast->_lingoArchive->addCode(_script, kMovieScript, 0, nullptr, kLPPTrimGarbage);
_changedBy = fileInfo.strings[1].readString();
_createdBy = fileInfo.strings[2].readString();
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index b2a1d127a14..7ecab21bcee 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1787,7 +1787,7 @@ void Score::loadActions(Common::SeekableReadStreamEndian &stream) {
if (ConfMan.getBool("dump_scripts"))
_movie->getCast()->dumpScript(j._value.c_str(), kScoreScript, j._key);
- _movie->getMainLingoArch()->addCode(j._value, kScoreScript, j._key);
+ _movie->getMainLingoArch()->addCode(j._value, kScoreScript, j._key, nullptr, kLPPTrimGarbage);
processImmediateFrameScript(j._value, j._key);
}
Commit: 32d6c312cefdf60a92110e9451d262b101e88410
https://github.com/scummvm/scummvm/commit/32d6c312cefdf60a92110e9451d262b101e88410
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Add 15fps quirk for Hell Cab
Changed paths:
engines/director/game-quirks.cpp
diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index ae24855c550..d2e85c5d966 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -198,6 +198,10 @@ struct Quirk {
{ "easternmind", Common::kPlatformMacintosh, &quirkLimit15FPS },
{ "easternmind", Common::kPlatformWindows, &quirkLimit15FPS },
+ // Sections of Hell Cab such as the prehistoric times need capped framerate.
+ { "hellcab", Common::kPlatformMacintosh, &quirkLimit15FPS },
+ { "hellcab", Common::kPlatformWindows, &quirkLimit15FPS },
+
// Wrath of the Gods has shooting gallery minigames which are
// clocked to 60fps; in reality this is far too fast to be playable.
{ "wrath", Common::kPlatformMacintosh, &quirkLimit15FPS },
Commit: 91857fecb450f8d874f3c52b7ff9bcd3875e37e9
https://github.com/scummvm/scummvm/commit/91857fecb450f8d874f3c52b7ff9bcd3875e37e9
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
IMAGES: Add Indeo 3 to QuickTime codec list
Changed paths:
image/codecs/codec.cpp
diff --git a/image/codecs/codec.cpp b/image/codecs/codec.cpp
index 8a28dd9c2aa..df90d17f911 100644
--- a/image/codecs/codec.cpp
+++ b/image/codecs/codec.cpp
@@ -253,7 +253,7 @@ Codec *createBitmapCodec(uint32 tag, uint32 streamTag, int width, int height, in
Codec *createQuickTimeCodec(uint32 tag, int width, int height, int bitsPerPixel) {
switch (tag) {
case MKTAG('c','v','i','d'):
- // Cinepak: As used by most Myst and all Riven videos as well as some Myst ME videos. "The Chief" videos also use this.
+ // Cinepak: As used by most Myst and all Riven videos as well as some Myst ME videos. "The Chief" videos also use this. Very popular for Director titles.
return new CinepakDecoder(bitsPerPixel);
case MKTAG('r','p','z','a'):
// Apple Video ("Road Pizza"): Used by some Myst videos.
@@ -280,6 +280,9 @@ Codec *createQuickTimeCodec(uint32 tag, int width, int height, int bitsPerPixel)
case MKTAG('r','a','w',' '):
// Used my L-Zone-mac (Director game)
return new BitmapRawDecoder(width, height, bitsPerPixel, true, true);
+ case MKTAG('I','V','3','2'):
+ // Indeo 3: Used by Team Xtreme: Operation Weather Disaster (Spanish)
+ return new Indeo3Decoder(width, height, bitsPerPixel);
default:
warning("Unsupported QuickTime codec \'%s\'", tag2str(tag));
}
Commit: 517a1563dfe44630d6efb398c04702fe0cb7b740
https://github.com/scummvm/scummvm/commit/517a1563dfe44630d6efb398c04702fe0cb7b740
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Make sprite dragging relative to the mouse click
Fixes putting the quarter into the binoculars in Hell Cab.
Fixes most of the demos in Face Kit.
Changed paths:
engines/director/channel.cpp
engines/director/events.cpp
engines/director/movie.h
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 207eb8486fb..f24b985ee0d 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -362,7 +362,7 @@ Common::Rect Channel::getBbox(bool unstretched) {
// Otherwise, use the Sprite dimensions and position (i.e. taken from the
// frame data in the Score).
// Setting unstretched to true always returns the Sprite dimensions.
- bool useOverride = (isShape || _sprite->_puppet) && !unstretched;
+ bool useOverride = (isShape || _sprite->_puppet || _sprite->_moveable) && !unstretched;
Common::Rect result(
useOverride ? _width : _sprite->_width,
@@ -629,7 +629,14 @@ void Channel::setPosition(int x, int y, bool force) {
newPos.y = MIN(constraintBbox.bottom, MAX(constraintBbox.top, newPos.y));
}
_currentPoint = newPos;
- _sprite->_startPoint = _currentPoint;
+ // Very occasionally, setPosition should override the
+ // sprite copy of the position.
+ // This is necessary for cases where aspects of the sprite
+ // are modified by the score, except for the position
+ // (e.g. dragging the animated parts in Face Kit)
+ if (force) {
+ _sprite->_startPoint = newPos;
+ }
// Based on Director in a Nutshell, page 15
_sprite->setAutoPuppet(kAPLoc, true);
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 2d5714c9c03..9afcb62c624 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -158,14 +158,13 @@ bool Movie::processEvent(Common::Event &event) {
if (_currentDraggedChannel) {
if (_currentDraggedChannel->_sprite->_moveable) {
- pos = _window->getMousePos();
+ pos = _draggingSpriteOffset + _window->getMousePos();
if (!_currentDraggedChannel->_sprite->_trails) {
g_director->getCurrentMovie()->getWindow()->addDirtyRect(_currentDraggedChannel->getBbox());
}
_currentDraggedChannel->setPosition(pos.x, pos.y, true);
_currentDraggedChannel->_dirty = true;
g_director->getCurrentMovie()->getWindow()->addDirtyRect(_currentDraggedChannel->getBbox());
- _draggingSpritePos = pos;
} else {
_currentDraggedChannel = nullptr;
}
@@ -218,7 +217,7 @@ bool Movie::processEvent(Common::Event &event) {
queueUserEvent(kEventMouseDown, spriteId);
if (sc->_channels[spriteId]->_sprite->_moveable) {
- _draggingSpritePos = _window->getMousePos();
+ _draggingSpriteOffset = sc->_channels[spriteId]->_currentPoint - _window->getMousePos();
_currentDraggedChannel = sc->_channels[spriteId];
}
}
diff --git a/engines/director/movie.h b/engines/director/movie.h
index f232be6ad3e..2be14372837 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -202,7 +202,7 @@ private:
bool _mouseDownWasInButton;
Channel *_currentDraggedChannel;
- Common::Point _draggingSpritePos;
+ Common::Point _draggingSpriteOffset;
};
} // End of namespace Director
Commit: 21bc268d49b6b2c1077c82e01d2fc0ef1fff3c6e
https://github.com/scummvm/scummvm/commit/21bc268d49b6b2c1077c82e01d2fc0ef1fff3c6e
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Add CD detection quirk for PAWS
Changed paths:
engines/director/game-quirks.cpp
diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index d2e85c5d966..e3332fc1ecd 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -92,6 +92,12 @@ struct CachedFile {
"WINDOWS/TX2SAVES",
(const byte *)"", 0
},
+ { "paws", Common::kPlatformWindows,
+ // PAWS: Personal Automated Wagging System checks a file to determine
+ // the location of the CD.
+ "INSTALL.INF",
+ (const byte *)"CDDrive=D:\\\r\nSourcePath=D:\\\r\nDestPath=C:\\", -1
+ },
{ nullptr, Common::kPlatformUnknown, nullptr, nullptr, 0 }
};
Commit: 565be3d3c9d25acfe9c2a4fe29767fb31e1782ab
https://github.com/scummvm/scummvm/commit/565be3d3c9d25acfe9c2a4fe29767fb31e1782ab
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Cache cast member when processing mouseDown/mouseUp
Fixes clicking the movement buttons in P.A.W.S.
Changed paths:
engines/director/events.cpp
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-events.cpp
engines/director/lingo/lingo-the.cpp
engines/director/movie.cpp
engines/director/movie.h
engines/director/score.cpp
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 9afcb62c624..9914fdc4859 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -41,9 +41,9 @@ namespace Director {
uint32 DirectorEngine::getMacTicks() { return (g_system->getMillis() * 60 / 1000.) - _tickBaseline; }
bool DirectorEngine::processEvents(bool captureClick, bool skipWindowManager) {
- debugC(5, kDebugEvents, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
- debugC(5, kDebugEvents, "@@@@ Processing events");
- debugC(5, kDebugEvents, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+ debugC(9, kDebugEvents, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ debugC(9, kDebugEvents, "@@@@ Processing events");
+ debugC(9, kDebugEvents, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
@@ -187,9 +187,9 @@ bool Movie::processEvent(Common::Event &event) {
else
spriteId = sc->getMouseSpriteIDFromPos(pos);
- // Set `the clickOn` Lingo property.
- // Even in D4, `the clickOn` uses the old "active" sprite instead of mouse sprite.
- _currentClickOnSpriteId = sc->getActiveSpriteIDFromPos(pos);
+ _currentActiveSpriteId = sc->getActiveSpriteIDFromPos(pos);
+ _currentMouseSpriteId = sc->getMouseSpriteIDFromPos(pos);
+ _currentMouseDownCastID = sc->_channels[spriteId]->_sprite->_castId;
if (!spriteId && _isBeepOn) {
g_lingo->func_beep(1);
@@ -229,9 +229,9 @@ bool Movie::processEvent(Common::Event &event) {
pos = _window->getMousePos();
if (g_director->getVersion() < 400)
- spriteId = sc->getActiveSpriteIDFromPos(pos);
+ spriteId = _currentActiveSpriteId;
else
- spriteId = sc->getMouseSpriteIDFromPos(pos);
+ spriteId = _currentMouseSpriteId;
if (_currentHiliteChannelId && sc->_channels[_currentHiliteChannelId]) {
g_director->getCurrentWindow()->setDirty(true);
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 0486bd7aaeb..e0775a7f7d4 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1416,7 +1416,6 @@ void LB::b_continue(int nargs) {
void LB::b_dontPassEvent(int nargs) {
g_lingo->_passEvent = false;
- warning("dontPassEvent raised");
}
void LB::b_nothing(int nargs) {
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 4fa2840be86..a13737f316b 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -143,9 +143,17 @@ void Movie::queueSpriteEvent(Common::Queue<LingoEvent> &queue, LEvent event, int
}
// Cast script
- ScriptContext *script = getScriptContext(kCastScript, sprite->_castId);
+ CastMemberID targetCast = sprite->_castId;
+
+ // In the case of clicking the mouse, it is possible for a mouseDown action to
+ // change the cast member underneath. on mouseUp should try and load the cast
+ // script for the original cast member, not the new one.
+ if (event == kEventMouseUp) {
+ targetCast = _currentMouseDownCastID;
+ }
+ ScriptContext *script = getScriptContext(kCastScript, targetCast);
if (script && script->_eventHandlers.contains(event)) {
- queue.push(LingoEvent(event, eventId, kCastScript, sprite->_castId, false, spriteId));
+ queue.push(LingoEvent(event, eventId, kCastScript, targetCast, false, spriteId));
}
}
@@ -351,8 +359,12 @@ void Lingo::processEvents(Common::Queue<LingoEvent> &queue) {
if (sc->_playState == kPlayStopped && el.event != kEventStopMovie)
continue;
- if (lastEventId == el.eventId && !_passEvent)
+ if (lastEventId == el.eventId && !_passEvent) {
+ debugC(5, kDebugEvents, "Lingo::processEvents: swallowed event (%s, %s, %s, %d) because _passEvent was false",
+ _eventHandlerTypes[el.event], scriptType2str(el.scriptType), el.scriptId.asString().c_str(), el.channelId
+ );
continue;
+ }
_passEvent = el.passByDefault;
processEvent(el.event, el.scriptType, el.scriptId, el.channelId);
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 1244d01ed9e..10db7194ebe 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -424,7 +424,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
d.type = POINT;
break;
case kTheClickOn:
- d = (int)movie->_currentClickOnSpriteId;
+ // Even in D4, `the clickOn` uses the old "active" sprite instead of mouse sprite.
+ d = (int)movie->_currentActiveSpriteId;
break;
case kTheColorDepth:
// bpp. 1, 2, 4, 8, 32
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index af5b8703532..068ea19c588 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -48,7 +48,8 @@ Movie::Movie(Window *window) {
_flags = 0;
_stageColor = _window->_wm->_colorWhite;
- _currentClickOnSpriteId = 0;
+ _currentActiveSpriteId = 0;
+ _currentMouseSpriteId = 0;
_currentEditableTextChannel = 0;
_lastEventTime = _vm->getMacTicks();
_lastKeyTime = _lastEventTime;
diff --git a/engines/director/movie.h b/engines/director/movie.h
index 2be14372837..d8efafa39e7 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -143,7 +143,9 @@ public:
uint16 _version;
Common::Platform _platform;
Common::Rect _movieRect;
- uint16 _currentClickOnSpriteId;
+ uint16 _currentActiveSpriteId;
+ uint16 _currentMouseSpriteId;
+ CastMemberID _currentMouseDownCastID;
uint16 _currentEditableTextChannel;
uint32 _lastEventTime;
uint32 _lastRollTime;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 7ecab21bcee..1c0873a10a3 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1818,13 +1818,13 @@ Common::String Score::formatChannelInfo() {
Channel &channel = *_channels[i + 1];
Sprite &sprite = *channel._sprite;
if (sprite._castId.member) {
- result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, stretch: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, moveable: %d\n",
+ result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, stretch: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, moveable: %d, movieRate: %f, movieTime: %d (%f)\n",
i + 1, sprite._castId.asString().c_str(), channel._visible, sprite._inkData,
sprite._ink, sprite._trails, sprite._stretch, sprite._thickness, channel._width, channel._height,
channel._currentPoint.x, channel._currentPoint.y,
sprite._spriteType, spriteType2str(sprite._spriteType), sprite._foreColor, sprite._backColor,
sprite._scriptId.asString().c_str(), sprite._colorcode, sprite._blendAmount, sprite._unk3,
- channel._constraint, sprite._puppet, sprite._moveable);
+ channel._constraint, sprite._puppet, sprite._moveable, channel._movieRate, channel._movieTime, (float)(channel._movieTime/60.0f));
} else {
result += Common::String::format("CH: %-3d castId: 000\n", i + 1);
}
Commit: c7e4f6737a9b2507ba62d715a04321168f7b7c7d
https://github.com/scummvm/scummvm/commit/c7e4f6737a9b2507ba62d715a04321168f7b7c7d
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: LINGO: Allow negateData for VOID
Fixes crash in the jetpack game in P.A.W.S.
Changed paths:
engines/director/lingo/lingo-code.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index bb2d4846a5b..29238624b05 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -850,6 +850,8 @@ Datum LC::negateData(Datum &d) {
res = Datum(-d.asInt());
} else if (d.type == FLOAT) {
res = Datum(-d.asFloat());
+ } else if (d.type == VOID) {
+ res = Datum(0);
} else {
g_lingo->lingoError("LC::negateData(): not supported for type %s", d.type2str());
}
Commit: 0ae7c151b48a826193992d3fc98bb33d2ae27669
https://github.com/scummvm/scummvm/commit/0ae7c151b48a826193992d3fc98bb33d2ae27669
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Fix DigitalVideoCastMember frame buffering
It is possible to have a DigitalVideoCastMember, in the stopped state,
that is moved using the movieTime property. Doing so needs to adjust what
frame is visible in the widget.
Fixes the first-person eye video playback in P.A.W.S.
Changed paths:
engines/director/castmember/digitalvideo.cpp
engines/director/castmember/digitalvideo.h
diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index f68280e175a..e0f27ded3d0 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -66,6 +66,7 @@ DigitalVideoCastMember::DigitalVideoCastMember(Cast *cast, uint16 castId, Common
_enableSound = _vflags & 0x08;
_crop = !(_vflags & 0x02);
_center = _vflags & 0x01;
+ _dirty = false;
if (debugChannelSet(2, kDebugLoading))
_initialRect.debugPrint(2, "DigitalVideoCastMember(): rect:");
@@ -141,6 +142,11 @@ bool DigitalVideoCastMember::isModified() {
if (!_video || !_video->isVideoLoaded())
return true;
+ if (_dirty) {
+ _dirty = false;
+ return true;
+ }
+
// Inelegant, but necessary. isModified will get called on
// every screen update, so use it to keep the playback
// status up to date.
@@ -300,6 +306,12 @@ void DigitalVideoCastMember::seekMovie(int stamp) {
Audio::Timestamp dur = _video->getDuration();
_video->seek(Audio::Timestamp(_channel->_startTime * 1000 / 60, dur.framerate()));
+
+ if (_channel->_movieRate == 0.0) {
+ _getFirstFrame = true;
+ }
+
+ _dirty = true;
}
void DigitalVideoCastMember::setStopTime(int stamp) {
diff --git a/engines/director/castmember/digitalvideo.h b/engines/director/castmember/digitalvideo.h
index 9073e87fefd..ab7397e2939 100644
--- a/engines/director/castmember/digitalvideo.h
+++ b/engines/director/castmember/digitalvideo.h
@@ -75,6 +75,7 @@ public:
bool _showControls;
bool _directToStage;
bool _avimovie, _qtmovie;
+ bool _dirty;
FrameRateType _frameRateType;
uint16 _frameRate;
Commit: c8d8facf01e1272bf300f0ba4b0914e67c23f94d
https://github.com/scummvm/scummvm/commit/c8d8facf01e1272bf300f0ba4b0914e67c23f94d
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Always disable loop flag for linked sounds
Fixes most sound effects in P.A.W.S.
Changed paths:
engines/director/castmember/sound.cpp
diff --git a/engines/director/castmember/sound.cpp b/engines/director/castmember/sound.cpp
index 80619eb9847..892f0922977 100644
--- a/engines/director/castmember/sound.cpp
+++ b/engines/director/castmember/sound.cpp
@@ -86,6 +86,9 @@ void SoundCastMember::load() {
debugC(2, kDebugLoading, "****** Loading file '%s', cast id: %d", filename.c_str(), sndId);
AudioFileDecoder *audio = new AudioFileDecoder(filename);
_audio = audio;
+
+ // Linked sound files always have the loop flag disabled
+ _looping = 0;
} else {
warning("Sound::load(): no resource or info found for cast member %d, skipping", _castId);
}
Commit: 2feaae3b93c5b97948c912707aedb919dde24763
https://github.com/scummvm/scummvm/commit/2feaae3b93c5b97948c912707aedb919dde24763
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: XOBJ: Add XObjects for Virtual Nightclub
Changed paths:
A engines/director/lingo/xlibs/dllglue.cpp
A engines/director/lingo/xlibs/dllglue.h
A engines/director/lingo/xlibs/instobj.cpp
A engines/director/lingo/xlibs/instobj.h
A engines/director/lingo/xlibs/mmovie.cpp
A engines/director/lingo/xlibs/mmovie.h
engines/director/lingo/lingo-object.cpp
engines/director/lingo/xlibs/movutils.cpp
engines/director/module.mk
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 74ff61b5464..838223e23a8 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -45,6 +45,7 @@
#include "director/lingo/xlibs/developerStack.h"
#include "director/lingo/xlibs/dialogsxobj.h"
#include "director/lingo/xlibs/dirutil.h"
+#include "director/lingo/xlibs/dllglue.h"
#include "director/lingo/xlibs/dpwavi.h"
#include "director/lingo/xlibs/dpwqtw.h"
#include "director/lingo/xlibs/draw.h"
@@ -68,6 +69,7 @@
#include "director/lingo/xlibs/getscreensizexfcn.h"
#include "director/lingo/xlibs/gpid.h"
#include "director/lingo/xlibs/hitmap.h"
+#include "director/lingo/xlibs/instobj.h"
#include "director/lingo/xlibs/jwxini.h"
#include "director/lingo/xlibs/iscd.h"
#include "director/lingo/xlibs/ispippin.h"
@@ -80,6 +82,7 @@
#include "director/lingo/xlibs/misc.h"
#include "director/lingo/xlibs/miscx.h"
#include "director/lingo/xlibs/mmaskxobj.h"
+#include "director/lingo/xlibs/mmovie.h"
#include "director/lingo/xlibs/moovxobj.h"
#include "director/lingo/xlibs/movemousexobj.h"
#include "director/lingo/xlibs/movieidxxobj.h"
@@ -203,6 +206,7 @@ static struct XLibProto {
{ ColorCursorXObj::fileNames, ColorCursorXObj::open, ColorCursorXObj::close, kXObj, 400 }, // D4
{ ConsumerXObj::fileNames, ConsumerXObj::open, ConsumerXObj::close, kXObj, 400 }, // D4
{ CursorXObj::fileNames, CursorXObj::open, CursorXObj::close, kXObj, 400 }, // D4
+ { DLLGlueXObj::fileNames, DLLGlueXObj::open, DLLGlueXObj::close, kXObj, 400 }, // D4
{ DPWAVIXObj::fileNames, DPWAVIXObj::open, DPWAVIXObj::close, kXObj, 300 }, // D3
{ DPWQTWXObj::fileNames, DPWQTWXObj::open, DPWQTWXObj::close, kXObj, 300 }, // D3
{ DarkenScreen::fileNames, DarkenScreen::open, DarkenScreen::close, kXObj, 300 }, // D3
@@ -230,11 +234,13 @@ static struct XLibProto {
{ GetScreenSizeXFCN::fileNames, GetScreenSizeXFCN::open, GetScreenSizeXFCN::close, kXObj, 300 }, // D3
{ GpidXObj::fileNames, GpidXObj::open, GpidXObj::close, kXObj, 400 }, // D4
{ HitMap::fileNames, HitMap::open, HitMap::close, kXObj, 400 }, // D4
+ { InstObjXObj::fileNames, InstObjXObj::open, InstObjXObj::close, kXObj, 400 }, // D4
{ IsCD::fileNames, IsCD::open, IsCD::close, kXObj, 300 }, // D3
{ IsPippin::fileNames, IsPippin::open, IsPippin::close, kXObj, 400 }, // D4
{ JITDraw3XObj::fileNames, JITDraw3XObj::open, JITDraw3XObj::close, kXObj, 400 }, // D4
{ JourneyWareXINIXObj::fileNames, JourneyWareXINIXObj::open, JourneyWareXINIXObj::close, kXObj, 400 }, // D4
{ LabelDrvXObj::fileNames, LabelDrvXObj::open, LabelDrvXObj::close, kXObj, 400 }, // D4
+ { MMovieXObj::fileNames, MMovieXObj::open, MMovieXObj::close, kXObj, 400 }, // D4
{ ManiacBgXObj::fileNames, ManiacBgXObj::open, ManiacBgXObj::close, kXObj, 300 }, // D3
{ MapNavigatorXObj::fileNames, MapNavigatorXObj::open, MapNavigatorXObj::close, kXObj, 400 }, // D4
{ MemCheckXObj::fileNames, MemCheckXObj::open, MemCheckXObj::close, kXObj, 400 }, // D4
@@ -243,6 +249,7 @@ static struct XLibProto {
{ MiscX::fileNames, MiscX::open, MiscX::close, kXObj, 400 }, // D4
{ MMaskXObj::fileNames, MMaskXObj::open, MMaskXObj::close, kXObj, 400 }, // D4
{ MoovXObj::fileNames, MoovXObj::open, MoovXObj::close, kXObj, 300 }, // D3
+ { MovUtilsXObj::fileNames, MovUtilsXObj::open, MovUtilsXObj::close, kXObj, 400 }, // D4
{ MoveMouseXObj::fileNames, MoveMouseXObj::open, MoveMouseXObj::close, kXObj, 400 }, // D4
{ MovieIdxXObj::fileNames, MovieIdxXObj::open, MovieIdxXObj::close, kXObj, 400 }, // D4
{ MovUtilsXObj::fileNames, MovUtilsXObj::open, MovUtilsXObj::close, kXObj, 400 }, // D4
diff --git a/engines/director/lingo/xlibs/dllglue.cpp b/engines/director/lingo/xlibs/dllglue.cpp
new file mode 100644
index 00000000000..0fd05fb3b75
--- /dev/null
+++ b/engines/director/lingo/xlibs/dllglue.cpp
@@ -0,0 +1,109 @@
+/* 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/dllglue.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * Virtual Nightclub
+ *
+ **************************************************/
+
+/*
+-- DLLGlue External Factory. Dec 1994 PTH (P.HAMILTON at APPLELINK.COM)
+--DLLGlue
+ISSSS mNew lib, proc, ret, args --Creates a new instance of the XObject
+S mName --Returns the XObject name (DLLGlue)
+V mCall --Returns an integer status code
+I mStatus --Returns an integer status code
+SI mError, code --Returns an error string (for above codes)
+S mLastError --Returns last error string
+I mWindowHandle --Returns handle for DPW stage window
+S mComment --Return UserCode comment
+X mDebug --write debugging info to message window
+ */
+
+namespace Director {
+
+const char *DLLGlueXObj::xlibName = "DLLGlue";
+const char *DLLGlueXObj::fileNames[] = {
+ "DLLGLUE",
+ nullptr
+};
+
+static MethodProto xlibMethods[] = {
+ { "new", DLLGlueXObj::m_new, 4, 4, 400 },
+ { "name", DLLGlueXObj::m_name, 0, 0, 400 },
+ { "call", DLLGlueXObj::m_call, 0, 0, 400 },
+ { "status", DLLGlueXObj::m_status, 0, 0, 400 },
+ { "error", DLLGlueXObj::m_error, 1, 1, 400 },
+ { "lastError", DLLGlueXObj::m_lastError, 0, 0, 400 },
+ { "windowHandle", DLLGlueXObj::m_windowHandle, 0, 0, 400 },
+ { "comment", DLLGlueXObj::m_comment, 0, 0, 400 },
+ { "debug", DLLGlueXObj::m_debug, 0, 0, 400 },
+ { nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+DLLGlueXObject::DLLGlueXObject(ObjectType ObjectType) :Object<DLLGlueXObject>("DLLGlueXObj") {
+ _objType = ObjectType;
+}
+
+void DLLGlueXObj::open(ObjectType type, const Common::Path &path) {
+ DLLGlueXObject::initMethods(xlibMethods);
+ DLLGlueXObject *xobj = new DLLGlueXObject(type);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void DLLGlueXObj::close(ObjectType type) {
+ DLLGlueXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void DLLGlueXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("DLLGlueXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
+ g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUB(DLLGlueXObj::m_name, "")
+XOBJSTUB(DLLGlueXObj::m_call, 0)
+XOBJSTUB(DLLGlueXObj::m_status, 0)
+XOBJSTUB(DLLGlueXObj::m_error, "")
+XOBJSTUB(DLLGlueXObj::m_lastError, "")
+XOBJSTUB(DLLGlueXObj::m_windowHandle, 0)
+XOBJSTUB(DLLGlueXObj::m_comment, "")
+XOBJSTUBNR(DLLGlueXObj::m_debug)
+
+}
diff --git a/engines/director/lingo/xlibs/dllglue.h b/engines/director/lingo/xlibs/dllglue.h
new file mode 100644
index 00000000000..d3c0d5794fa
--- /dev/null
+++ b/engines/director/lingo/xlibs/dllglue.h
@@ -0,0 +1,54 @@
+/* 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_DLLGLUE_H
+#define DIRECTOR_LINGO_XLIBS_DLLGLUE_H
+
+namespace Director {
+
+class DLLGlueXObject : public Object<DLLGlueXObject> {
+public:
+ DLLGlueXObject(ObjectType objType);
+};
+
+namespace DLLGlueXObj {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_name(int nargs);
+void m_call(int nargs);
+void m_status(int nargs);
+void m_error(int nargs);
+void m_lastError(int nargs);
+void m_windowHandle(int nargs);
+void m_comment(int nargs);
+void m_debug(int nargs);
+
+} // End of namespace DLLGlueXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/instobj.cpp b/engines/director/lingo/xlibs/instobj.cpp
new file mode 100644
index 00000000000..7f4dcbb8a22
--- /dev/null
+++ b/engines/director/lingo/xlibs/instobj.cpp
@@ -0,0 +1,144 @@
+/* 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/instobj.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * Virtual Nightclub
+ *
+ **************************************************/
+
+/*
+-- InstObj Installer XObject. Andy Wilson, Tape Gallery Multimedia, 20th March 1996
+--InstObj
+I mNew --Creates a new instance of the XObject
+X mDispose --Disposes of XObject instance
+S mName --Returns the XObject name (InstObj)
+I mStatus --Returns an integer status code
+SI mError, code --Returns an error string
+S mLastError --Returns last error string
+S mGetWinDir --Returns the Windows directory
+S mGetSysDir --Returns the System directory
+S mGetWinVer --Returns the Windows version
+S mGetProcInfo --Returns the processor type
+SI mGetDriveType, Drive --Make a new directory (A=0, B=1, etc.)
+II mGetFreeSpace, Drive --Returns the free space in Kb (A=0, B=1, etc.)
+IS mMakeDir, DirName --Make a new directory
+IS mDirExists, DirName --Checks that a directory exists
+ISS mCopyFile, Source,Dest --Copy a file
+IS mDeleteFile, File --Delete a file
+IS mFileExists, File --Returns 0 if the file exists
+IS mAddPMGroup, Group --Add a program manager group
+ISSSSI mAddPMItem, Group,CmndLine,ItemName,IconPath,IconIndex --Add a program manager item
+SSSSS mReadProfile, File,Section,Item,Default --Read an INI profile string
+ISSSS mWriteProfile, File,Section,Item,NewVal --Write an INI profile string
+ */
+
+namespace Director {
+
+const char *InstObjXObj::xlibName = "InstObj";
+const char *InstObjXObj::fileNames[] = {
+ "INSTOBJ",
+ nullptr
+};
+
+static MethodProto xlibMethods[] = {
+ { "new", InstObjXObj::m_new, 0, 0, 400 },
+ { "dispose", InstObjXObj::m_dispose, 0, 0, 400 },
+ { "name", InstObjXObj::m_name, 0, 0, 400 },
+ { "status", InstObjXObj::m_status, 0, 0, 400 },
+ { "error", InstObjXObj::m_error, 1, 1, 400 },
+ { "lastError", InstObjXObj::m_lastError, 0, 0, 400 },
+ { "getWinDir", InstObjXObj::m_getWinDir, 0, 0, 400 },
+ { "getSysDir", InstObjXObj::m_getSysDir, 0, 0, 400 },
+ { "getWinVer", InstObjXObj::m_getWinVer, 0, 0, 400 },
+ { "getProcInfo", InstObjXObj::m_getProcInfo, 0, 0, 400 },
+ { "getDriveType", InstObjXObj::m_getDriveType, 1, 1, 400 },
+ { "getFreeSpace", InstObjXObj::m_getFreeSpace, 1, 1, 400 },
+ { "makeDir", InstObjXObj::m_makeDir, 1, 1, 400 },
+ { "dirExists", InstObjXObj::m_dirExists, 1, 1, 400 },
+ { "copyFile", InstObjXObj::m_copyFile, 2, 2, 400 },
+ { "deleteFile", InstObjXObj::m_deleteFile, 1, 1, 400 },
+ { "fileExists", InstObjXObj::m_fileExists, 1, 1, 400 },
+ { "addPMGroup", InstObjXObj::m_addPMGroup, 1, 1, 400 },
+ { "addPMItem", InstObjXObj::m_addPMItem, 5, 5, 400 },
+ { "readProfile", InstObjXObj::m_readProfile, 4, 4, 400 },
+ { "writeProfile", InstObjXObj::m_writeProfile, 4, 4, 400 },
+ { nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+InstObjXObject::InstObjXObject(ObjectType ObjectType) :Object<InstObjXObject>("InstObjXObj") {
+ _objType = ObjectType;
+}
+
+void InstObjXObj::open(ObjectType type, const Common::Path &path) {
+ InstObjXObject::initMethods(xlibMethods);
+ InstObjXObject *xobj = new InstObjXObject(type);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void InstObjXObj::close(ObjectType type) {
+ InstObjXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void InstObjXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("InstObjXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
+ g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUBNR(InstObjXObj::m_dispose)
+XOBJSTUB(InstObjXObj::m_name, "")
+XOBJSTUB(InstObjXObj::m_status, 0)
+XOBJSTUB(InstObjXObj::m_error, "")
+XOBJSTUB(InstObjXObj::m_lastError, "")
+XOBJSTUB(InstObjXObj::m_getWinDir, "")
+XOBJSTUB(InstObjXObj::m_getSysDir, "")
+XOBJSTUB(InstObjXObj::m_getWinVer, "")
+XOBJSTUB(InstObjXObj::m_getProcInfo, "")
+XOBJSTUB(InstObjXObj::m_getDriveType, "")
+XOBJSTUB(InstObjXObj::m_getFreeSpace, 0)
+XOBJSTUB(InstObjXObj::m_makeDir, 0)
+XOBJSTUB(InstObjXObj::m_dirExists, 0)
+XOBJSTUB(InstObjXObj::m_copyFile, 0)
+XOBJSTUB(InstObjXObj::m_deleteFile, 0)
+XOBJSTUB(InstObjXObj::m_fileExists, 0)
+XOBJSTUB(InstObjXObj::m_addPMGroup, 0)
+XOBJSTUB(InstObjXObj::m_addPMItem, 0)
+XOBJSTUB(InstObjXObj::m_readProfile, "")
+XOBJSTUB(InstObjXObj::m_writeProfile, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/instobj.h b/engines/director/lingo/xlibs/instobj.h
new file mode 100644
index 00000000000..1b5249ff01f
--- /dev/null
+++ b/engines/director/lingo/xlibs/instobj.h
@@ -0,0 +1,66 @@
+/* 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_INSTOBJ_H
+#define DIRECTOR_LINGO_XLIBS_INSTOBJ_H
+
+namespace Director {
+
+class InstObjXObject : public Object<InstObjXObject> {
+public:
+ InstObjXObject(ObjectType objType);
+};
+
+namespace InstObjXObj {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_name(int nargs);
+void m_status(int nargs);
+void m_error(int nargs);
+void m_lastError(int nargs);
+void m_getWinDir(int nargs);
+void m_getSysDir(int nargs);
+void m_getWinVer(int nargs);
+void m_getProcInfo(int nargs);
+void m_getDriveType(int nargs);
+void m_getFreeSpace(int nargs);
+void m_makeDir(int nargs);
+void m_dirExists(int nargs);
+void m_copyFile(int nargs);
+void m_deleteFile(int nargs);
+void m_fileExists(int nargs);
+void m_addPMGroup(int nargs);
+void m_addPMItem(int nargs);
+void m_readProfile(int nargs);
+void m_writeProfile(int nargs);
+
+} // End of namespace InstObjXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/mmovie.cpp b/engines/director/lingo/xlibs/mmovie.cpp
new file mode 100644
index 00000000000..34dd0dbd1ef
--- /dev/null
+++ b/engines/director/lingo/xlibs/mmovie.cpp
@@ -0,0 +1,161 @@
+/* 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/mmovie.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * Virtual Nightclub
+ *
+ **************************************************/
+
+/*
+Multi Movie XObject by Mediamation Ltd. Copyright © Trip Media Ltd 1995-1996.
+--MMovie
+I mNew
+X mDispose
+IS mOpenMMovie, fileName
+II mCloseMMovie, movieIndex
+ISSSSS mPlaySegment, segmentName, restoreOpt, abortOpt, purgeOpt, asyncOpt
+ISSSSS mPlaySegLoop, segmentName, restoreOpt, abortOpt, purgeOpt, asyncOpt
+I mIdleSegment
+I mStopSegment
+IS mSeekSegment, segmentName
+II mSetSegmentTime, segTime
+IIIII mSetDisplayBounds, left, top, right, bottom
+II mGetMovieNormalWidth, movieIndex
+II mGetMovieNormalHeight, movieIndex
+II mGetSegCount, movieIndex
+SII mGetSegName, movieIndex, segmentIndex
+I mGetMovieRate
+II mSetMovieRate, ratePercent
+I mFlushEvents
+IIIII mInvalidateRect, left, top, right, bottom
+SSI mReadFile, fileName, scramble
+SSSI mWriteFile, fileName, data, scramble
+ISS mCopyFile, sourceFileName, destFileName
+I mCopyFileCont
+IS mFreeSpace, driveLetter
+IS mDeleteFile, fileName
+S mVolList
+ */
+
+namespace Director {
+
+const char *MMovieXObj::xlibName = "MMovie";
+const char *MMovieXObj::fileNames[] = {
+ "MMovie",
+ nullptr
+};
+
+static MethodProto xlibMethods[] = {
+ { "Movie", MMovieXObj::m_Movie, 4, 4, 400 },
+ { "new", MMovieXObj::m_new, 0, 0, 400 },
+ { "dispose", MMovieXObj::m_dispose, 0, 0, 400 },
+ { "openMMovie", MMovieXObj::m_openMMovie, 1, 1, 400 },
+ { "closeMMovie", MMovieXObj::m_closeMMovie, 1, 1, 400 },
+ { "playSegment", MMovieXObj::m_playSegment, 5, 5, 400 },
+ { "playSegLoop", MMovieXObj::m_playSegLoop, 5, 5, 400 },
+ { "idleSegment", MMovieXObj::m_idleSegment, 0, 0, 400 },
+ { "stopSegment", MMovieXObj::m_stopSegment, 0, 0, 400 },
+ { "seekSegment", MMovieXObj::m_seekSegment, 1, 1, 400 },
+ { "setSegmentTime", MMovieXObj::m_setSegmentTime, 1, 1, 400 },
+ { "setDisplayBounds", MMovieXObj::m_setDisplayBounds, 4, 4, 400 },
+ { "getMovieNormalWidth", MMovieXObj::m_getMovieNormalWidth, 1, 1, 400 },
+ { "getMovieNormalHeight", MMovieXObj::m_getMovieNormalHeight, 1, 1, 400 },
+ { "getSegCount", MMovieXObj::m_getSegCount, 1, 1, 400 },
+ { "getSegName", MMovieXObj::m_getSegName, 2, 2, 400 },
+ { "getMovieRate", MMovieXObj::m_getMovieRate, 0, 0, 400 },
+ { "setMovieRate", MMovieXObj::m_setMovieRate, 1, 1, 400 },
+ { "flushEvents", MMovieXObj::m_flushEvents, 0, 0, 400 },
+ { "invalidateRect", MMovieXObj::m_invalidateRect, 4, 4, 400 },
+ { "readFile", MMovieXObj::m_readFile, 2, 2, 400 },
+ { "writeFile", MMovieXObj::m_writeFile, 3, 3, 400 },
+ { "copyFile", MMovieXObj::m_copyFile, 2, 2, 400 },
+ { "copyFileCont", MMovieXObj::m_copyFileCont, 0, 0, 400 },
+ { "freeSpace", MMovieXObj::m_freeSpace, 1, 1, 400 },
+ { "deleteFile", MMovieXObj::m_deleteFile, 1, 1, 400 },
+ { "volList", MMovieXObj::m_volList, 0, 0, 400 },
+ { nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+MMovieXObject::MMovieXObject(ObjectType ObjectType) :Object<MMovieXObject>("MMovieXObj") {
+ _objType = ObjectType;
+}
+
+void MMovieXObj::open(ObjectType type, const Common::Path &path) {
+ MMovieXObject::initMethods(xlibMethods);
+ MMovieXObject *xobj = new MMovieXObject(type);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void MMovieXObj::close(ObjectType type) {
+ MMovieXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void MMovieXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("MMovieXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
+ g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUB(MMovieXObj::m_Movie, 0)
+XOBJSTUBNR(MMovieXObj::m_dispose)
+XOBJSTUB(MMovieXObj::m_openMMovie, 0)
+XOBJSTUB(MMovieXObj::m_closeMMovie, 0)
+XOBJSTUB(MMovieXObj::m_playSegment, 0)
+XOBJSTUB(MMovieXObj::m_playSegLoop, 0)
+XOBJSTUB(MMovieXObj::m_idleSegment, 0)
+XOBJSTUB(MMovieXObj::m_stopSegment, 0)
+XOBJSTUB(MMovieXObj::m_seekSegment, 0)
+XOBJSTUB(MMovieXObj::m_setSegmentTime, 0)
+XOBJSTUB(MMovieXObj::m_setDisplayBounds, 0)
+XOBJSTUB(MMovieXObj::m_getMovieNormalWidth, 0)
+XOBJSTUB(MMovieXObj::m_getMovieNormalHeight, 0)
+XOBJSTUB(MMovieXObj::m_getSegCount, 0)
+XOBJSTUB(MMovieXObj::m_getSegName, "")
+XOBJSTUB(MMovieXObj::m_getMovieRate, 0)
+XOBJSTUB(MMovieXObj::m_setMovieRate, 0)
+XOBJSTUB(MMovieXObj::m_flushEvents, 0)
+XOBJSTUB(MMovieXObj::m_invalidateRect, 0)
+XOBJSTUB(MMovieXObj::m_readFile, "")
+XOBJSTUB(MMovieXObj::m_writeFile, "")
+XOBJSTUB(MMovieXObj::m_copyFile, 0)
+XOBJSTUB(MMovieXObj::m_copyFileCont, 0)
+XOBJSTUB(MMovieXObj::m_freeSpace, 0)
+XOBJSTUB(MMovieXObj::m_deleteFile, 0)
+XOBJSTUB(MMovieXObj::m_volList, "")
+
+}
diff --git a/engines/director/lingo/xlibs/mmovie.h b/engines/director/lingo/xlibs/mmovie.h
new file mode 100644
index 00000000000..b38e071bef2
--- /dev/null
+++ b/engines/director/lingo/xlibs/mmovie.h
@@ -0,0 +1,72 @@
+/* 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_MMOVIE_H
+#define DIRECTOR_LINGO_XLIBS_MMOVIE_H
+
+namespace Director {
+
+class MMovieXObject : public Object<MMovieXObject> {
+public:
+ MMovieXObject(ObjectType objType);
+};
+
+namespace MMovieXObj {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_Movie(int nargs);
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_openMMovie(int nargs);
+void m_closeMMovie(int nargs);
+void m_playSegment(int nargs);
+void m_playSegLoop(int nargs);
+void m_idleSegment(int nargs);
+void m_stopSegment(int nargs);
+void m_seekSegment(int nargs);
+void m_setSegmentTime(int nargs);
+void m_setDisplayBounds(int nargs);
+void m_getMovieNormalWidth(int nargs);
+void m_getMovieNormalHeight(int nargs);
+void m_getSegCount(int nargs);
+void m_getSegName(int nargs);
+void m_getMovieRate(int nargs);
+void m_setMovieRate(int nargs);
+void m_flushEvents(int nargs);
+void m_invalidateRect(int nargs);
+void m_readFile(int nargs);
+void m_writeFile(int nargs);
+void m_copyFile(int nargs);
+void m_copyFileCont(int nargs);
+void m_freeSpace(int nargs);
+void m_deleteFile(int nargs);
+void m_volList(int nargs);
+
+} // End of namespace MMovieXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/movutils.cpp b/engines/director/lingo/xlibs/movutils.cpp
index e30220394bd..61964d48c48 100644
--- a/engines/director/lingo/xlibs/movutils.cpp
+++ b/engines/director/lingo/xlibs/movutils.cpp
@@ -24,6 +24,7 @@
* USED IN:
* Gahan Wilson's Ultimate Haunted House
* Momi no Ki no Shita de: The Day of St. Claus
+ * Virtual Nightclub
*
*************************************/
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 1e69e9b3902..f5bbb5050e7 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -69,6 +69,7 @@ MODULE_OBJS = \
lingo/xlibs/developerStack.o \
lingo/xlibs/dialogsxobj.o \
lingo/xlibs/dirutil.o \
+ lingo/xlibs/dllglue.o \
lingo/xlibs/dpwavi.o \
lingo/xlibs/dpwqtw.o \
lingo/xlibs/draw.o \
@@ -92,6 +93,7 @@ MODULE_OBJS = \
lingo/xlibs/getscreensizexfcn.o \
lingo/xlibs/gpid.o \
lingo/xlibs/hitmap.o \
+ lingo/xlibs/instobj.o \
lingo/xlibs/iscd.o \
lingo/xlibs/ispippin.o \
lingo/xlibs/jitdraw3.o \
@@ -104,6 +106,7 @@ MODULE_OBJS = \
lingo/xlibs/misc.o \
lingo/xlibs/miscx.o \
lingo/xlibs/mmaskxobj.o \
+ lingo/xlibs/mmovie.o \
lingo/xlibs/moovxobj.o \
lingo/xlibs/movemousexobj.o \
lingo/xlibs/movieidxxobj.o \
Commit: d27af65eb2e195c5be6a41fea8cc4db604be6c21
https://github.com/scummvm/scummvm/commit/d27af65eb2e195c5be6a41fea8cc4db604be6c21
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Make Virtual Nightclub run in 32bpp
Changed paths:
engines/director/detection_tables.h
diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index e182c675013..c75ef536277 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -5687,12 +5687,12 @@ static const DirectorGameDescription gameDescriptions[] = {
MACGAME1_l("virtualmuseum", "", "Virtual Museum Vol.1", "8b138db44d4421cc7294a9dc792ccf1b", 503337, Common::JA_JPN, 403),
- MACGAME2("vnc", "", "VNC/VNC", "r:0c7bbb4b24823e5ab871cb4c1d6f3710", 485860,
- "VNC2/SHARED.Dxr", "d:f215be3e2d40e68035725c14b262e9f5", 4525536, 404),
- WINGAME2("vnc", "", "VNC/VNC.EXE", "d:40ba00213a10164eb6e01847108f9b21", 1086869,
- "VNC2/SHARED.DXR", "d:f215be3e2d40e68035725c14b262e9f5", 4525536, 404),
- WINGAME2("vnc", "Beta", "VNC/VNC.EXE", "d:e6f284971c09f19e3277aa8ebcf58cbd", 726643,
- "VNC2/SHARED.DIR", "d:e3145060a7349e99e5b7ceffef000bad", 2782000, 404),
+ MACGAME2tf("vnc", "", "VNC/VNC", "r:0c7bbb4b24823e5ab871cb4c1d6f3710", 485860,
+ "VNC2/SHARED.Dxr", "d:f215be3e2d40e68035725c14b262e9f5", 4525536, 404, GF_32BPP),
+ WINGAME2tf("vnc", "", "VNC/VNC.EXE", "d:40ba00213a10164eb6e01847108f9b21", 1086869,
+ "VNC2/SHARED.DXR", "d:f215be3e2d40e68035725c14b262e9f5", 4525536, 404, GF_32BPP),
+ WINGAME2tf("vnc", "Beta", "VNC/VNC.EXE", "d:e6f284971c09f19e3277aa8ebcf58cbd", 726643,
+ "VNC2/SHARED.DIR", "d:e3145060a7349e99e5b7ceffef000bad", 2782000, 404, GF_32BPP),
// Mac version requires installation, 'Install Voodoo Lounge', StuffIt
MACGAME1("voodoolounge", "", "Voodoo Lounge", "b7e69c37b7355022d400c14aa97c5d54", 502080, 404),
Commit: 89ba3358609978c6c95361ab7c8d4deea0330ee8
https://github.com/scummvm/scummvm/commit/89ba3358609978c6c95361ab7c8d4deea0330ee8
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: XOBJ: Make object name match library name
It is possible for games to call factory("libName") to check if an
XObject has been opened, which requires the names to match.
Fixes the XObject loader in Virtual Nightclub.
Changed paths:
devtools/director-generate-xobj-stub.py
engines/director/lingo/xlibs/aiff.cpp
engines/director/lingo/xlibs/blitpict.cpp
engines/director/lingo/xlibs/consumer.cpp
engines/director/lingo/xlibs/cursorxobj.cpp
engines/director/lingo/xlibs/dirutil.cpp
engines/director/lingo/xlibs/dllglue.cpp
engines/director/lingo/xlibs/dpwavi.cpp
engines/director/lingo/xlibs/dpwqtw.cpp
engines/director/lingo/xlibs/draw.cpp
engines/director/lingo/xlibs/fedracul.cpp
engines/director/lingo/xlibs/feimasks.cpp
engines/director/lingo/xlibs/feiprefs.cpp
engines/director/lingo/xlibs/gpid.cpp
engines/director/lingo/xlibs/instobj.cpp
engines/director/lingo/xlibs/jwxini.cpp
engines/director/lingo/xlibs/maniacbg.cpp
engines/director/lingo/xlibs/mapnavigatorxobj.cpp
engines/director/lingo/xlibs/memcheckxobj.cpp
engines/director/lingo/xlibs/memoryxobj.cpp
engines/director/lingo/xlibs/mmovie.cpp
engines/director/lingo/xlibs/movemousexobj.cpp
engines/director/lingo/xlibs/movieidxxobj.cpp
engines/director/lingo/xlibs/movutils.cpp
engines/director/lingo/xlibs/paco.cpp
engines/director/lingo/xlibs/palxobj.cpp
engines/director/lingo/xlibs/panel.cpp
engines/director/lingo/xlibs/printomatic.cpp
engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
engines/director/lingo/xlibs/stagetc.cpp
engines/director/lingo/xlibs/valkyrie.cpp
engines/director/lingo/xlibs/widgetxobj.cpp
engines/director/lingo/xlibs/window.cpp
engines/director/lingo/xlibs/wininfo.cpp
engines/director/lingo/xlibs/winxobj.cpp
engines/director/lingo/xlibs/xcmdglue.cpp
engines/director/lingo/xlibs/xio.cpp
engines/director/lingo/xlibs/xwin.cpp
diff --git a/devtools/director-generate-xobj-stub.py b/devtools/director-generate-xobj-stub.py
index 053e20257a1..9b9d8cd3227 100755
--- a/devtools/director-generate-xobj-stub.py
+++ b/devtools/director-generate-xobj-stub.py
@@ -135,7 +135,7 @@ static BuiltinProto xlibTopLevel[] = {{
{{ nullptr, nullptr, 0, 0, 0, VOIDSYM }}
}};
-{xobject_class}::{xobject_class}(ObjectType ObjectType) :Object<{xobject_class}>("{xobj_class}") {{
+{xobject_class}::{xobject_class}(ObjectType ObjectType) :Object<{xobject_class}>("{name}") {{
_objType = ObjectType;
}}
diff --git a/engines/director/lingo/xlibs/aiff.cpp b/engines/director/lingo/xlibs/aiff.cpp
index 8937559e07b..eb5c9e5934e 100644
--- a/engines/director/lingo/xlibs/aiff.cpp
+++ b/engines/director/lingo/xlibs/aiff.cpp
@@ -83,7 +83,7 @@ void AiffXObj::close(ObjectType type) {
}
-AiffXObject::AiffXObject(ObjectType ObjectType) :Object<AiffXObject>("AiffXObj") {
+AiffXObject::AiffXObject(ObjectType ObjectType) :Object<AiffXObject>("Aiff") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/blitpict.cpp b/engines/director/lingo/xlibs/blitpict.cpp
index 457005e48da..82dd615be65 100644
--- a/engines/director/lingo/xlibs/blitpict.cpp
+++ b/engines/director/lingo/xlibs/blitpict.cpp
@@ -52,7 +52,7 @@ IIIIIIIIIIII mSparkle --Draws a sparkle from a bitmap
namespace Director {
-const char *BlitPictXObj::xlibName = "blitpict";
+const char *BlitPictXObj::xlibName = "BlitPict";
const char *BlitPictXObj::fileNames[] = {
"blitpict",
nullptr
@@ -72,7 +72,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-BlitPictXObject::BlitPictXObject(ObjectType ObjectType) :Object<BlitPictXObject>("BlitPictXObj") {
+BlitPictXObject::BlitPictXObject(ObjectType ObjectType) :Object<BlitPictXObject>("BlitPict") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/consumer.cpp b/engines/director/lingo/xlibs/consumer.cpp
index ac681a08d50..8c0ba340b00 100644
--- a/engines/director/lingo/xlibs/consumer.cpp
+++ b/engines/director/lingo/xlibs/consumer.cpp
@@ -52,7 +52,7 @@ I mHackMenu --Hack to destroy menu
namespace Director {
-const char *ConsumerXObj::xlibName = "consumer";
+const char *ConsumerXObj::xlibName = "Consumer";
const char *ConsumerXObj::fileNames[] = {
"consumer",
nullptr
@@ -78,7 +78,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-ConsumerXObject::ConsumerXObject(ObjectType ObjectType) :Object<ConsumerXObject>("ConsumerXObj") {
+ConsumerXObject::ConsumerXObject(ObjectType ObjectType) :Object<ConsumerXObject>("Consumer") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/cursorxobj.cpp b/engines/director/lingo/xlibs/cursorxobj.cpp
index e087beab45b..6e3323eaccc 100644
--- a/engines/director/lingo/xlibs/cursorxobj.cpp
+++ b/engines/director/lingo/xlibs/cursorxobj.cpp
@@ -44,7 +44,7 @@ XSS mSetCursor, cursorName, windowName --Sets the window cursor
namespace Director {
-const char *CursorXObj::xlibName = "cursorxobj";
+const char *CursorXObj::xlibName = "Cursor";
const char *CursorXObj::fileNames[] = {
"CURSOR",
nullptr
@@ -57,7 +57,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-CursorXObject::CursorXObject(ObjectType ObjectType) :Object<CursorXObject>("CursorXObj") {
+CursorXObject::CursorXObject(ObjectType ObjectType) :Object<CursorXObject>("Cursor") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/dirutil.cpp b/engines/director/lingo/xlibs/dirutil.cpp
index 437fdd248f2..8f80ef9089a 100644
--- a/engines/director/lingo/xlibs/dirutil.cpp
+++ b/engines/director/lingo/xlibs/dirutil.cpp
@@ -48,7 +48,7 @@ XI mSetErrorMode,mode --sets windoze error mode
namespace Director {
-const char *DirUtilXObj::xlibName = "dirutil";
+const char *DirUtilXObj::xlibName = "DirUtil";
const char *DirUtilXObj::fileNames[] = {
"dirutil",
nullptr
@@ -72,7 +72,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-DirUtilXObject::DirUtilXObject(ObjectType ObjectType) :Object<DirUtilXObject>("DirUtilXObj") {
+DirUtilXObject::DirUtilXObject(ObjectType ObjectType) :Object<DirUtilXObject>("DirUtil") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/dllglue.cpp b/engines/director/lingo/xlibs/dllglue.cpp
index 0fd05fb3b75..824af988a40 100644
--- a/engines/director/lingo/xlibs/dllglue.cpp
+++ b/engines/director/lingo/xlibs/dllglue.cpp
@@ -74,7 +74,7 @@ static BuiltinProto xlibBuiltins[] = {
{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
};
-DLLGlueXObject::DLLGlueXObject(ObjectType ObjectType) :Object<DLLGlueXObject>("DLLGlueXObj") {
+DLLGlueXObject::DLLGlueXObject(ObjectType ObjectType) :Object<DLLGlueXObject>("DLLGlue") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/dpwavi.cpp b/engines/director/lingo/xlibs/dpwavi.cpp
index a6035dda982..2c36fa5adc7 100644
--- a/engines/director/lingo/xlibs/dpwavi.cpp
+++ b/engines/director/lingo/xlibs/dpwavi.cpp
@@ -66,7 +66,7 @@ static BuiltinProto xlibBuiltins[] = {
{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
};
-DPWAVIXObject::DPWAVIXObject(ObjectType ObjectType) :Object<DPWAVIXObject>("DPWAVIXObj") {
+DPWAVIXObject::DPWAVIXObject(ObjectType ObjectType) :Object<DPWAVIXObject>("DPWAVI") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/dpwqtw.cpp b/engines/director/lingo/xlibs/dpwqtw.cpp
index 32e6157bae2..eb58e0cfcb1 100644
--- a/engines/director/lingo/xlibs/dpwqtw.cpp
+++ b/engines/director/lingo/xlibs/dpwqtw.cpp
@@ -66,7 +66,7 @@ static BuiltinProto xlibBuiltins[] = {
{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
};
-DPWQTWXObject::DPWQTWXObject(ObjectType ObjectType) :Object<DPWQTWXObject>("DPWQTWXObj") {
+DPWQTWXObject::DPWQTWXObject(ObjectType ObjectType) :Object<DPWQTWXObject>("DPWQTW") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/draw.cpp b/engines/director/lingo/xlibs/draw.cpp
index 6644e26a35d..13073cb6961 100644
--- a/engines/director/lingo/xlibs/draw.cpp
+++ b/engines/director/lingo/xlibs/draw.cpp
@@ -132,7 +132,7 @@ void DrawXObj::close(ObjectType type) {
}
-DrawXObject::DrawXObject(ObjectType ObjectType) :Object<DrawXObject>("DrawXObj") {
+DrawXObject::DrawXObject(ObjectType ObjectType) :Object<DrawXObject>("Draw") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/fedracul.cpp b/engines/director/lingo/xlibs/fedracul.cpp
index da78baee06e..2e3578d74cb 100644
--- a/engines/director/lingo/xlibs/fedracul.cpp
+++ b/engines/director/lingo/xlibs/fedracul.cpp
@@ -82,7 +82,7 @@ void FEDraculXObj::close(ObjectType type) {
}
-FEDraculXObject::FEDraculXObject(ObjectType ObjectType) : Object<FEDraculXObject>("FEDraculXObj") {
+FEDraculXObject::FEDraculXObject(ObjectType ObjectType) : Object<FEDraculXObject>("FEDracul") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/feimasks.cpp b/engines/director/lingo/xlibs/feimasks.cpp
index 9226da68d74..0338141a081 100644
--- a/engines/director/lingo/xlibs/feimasks.cpp
+++ b/engines/director/lingo/xlibs/feimasks.cpp
@@ -70,7 +70,7 @@ void FEIMasksXObj::close(ObjectType type) {
}
}
-FEIMasksXObject::FEIMasksXObject(ObjectType ObjectType) : Object<FEIMasksXObject>("FEIMasksXObj") {
+FEIMasksXObject::FEIMasksXObject(ObjectType ObjectType) : Object<FEIMasksXObject>("FEIMasks") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/feiprefs.cpp b/engines/director/lingo/xlibs/feiprefs.cpp
index 88a311a648e..0c67068e2cf 100644
--- a/engines/director/lingo/xlibs/feiprefs.cpp
+++ b/engines/director/lingo/xlibs/feiprefs.cpp
@@ -76,7 +76,7 @@ void FEIPrefsXObj::close(ObjectType type) {
}
-FEIPrefsXObject::FEIPrefsXObject(ObjectType ObjectType) : Object<FEIPrefsXObject>("FEIPrefsXObj") {
+FEIPrefsXObject::FEIPrefsXObject(ObjectType ObjectType) : Object<FEIPrefsXObject>("FEIPrefs") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/gpid.cpp b/engines/director/lingo/xlibs/gpid.cpp
index dea247ec04d..9fbbe0cad51 100644
--- a/engines/director/lingo/xlibs/gpid.cpp
+++ b/engines/director/lingo/xlibs/gpid.cpp
@@ -85,7 +85,7 @@ void GpidXObj::close(ObjectType type) {
}
-ProductIdXObject::ProductIdXObject(ObjectType ObjectType) :Object<ProductIdXObject>("GpidXObj") {
+ProductIdXObject::ProductIdXObject(ObjectType ObjectType) :Object<ProductIdXObject>("gpid") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/instobj.cpp b/engines/director/lingo/xlibs/instobj.cpp
index 7f4dcbb8a22..0fda4aa93c5 100644
--- a/engines/director/lingo/xlibs/instobj.cpp
+++ b/engines/director/lingo/xlibs/instobj.cpp
@@ -97,7 +97,7 @@ static BuiltinProto xlibBuiltins[] = {
{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
};
-InstObjXObject::InstObjXObject(ObjectType ObjectType) :Object<InstObjXObject>("InstObjXObj") {
+InstObjXObject::InstObjXObject(ObjectType ObjectType) :Object<InstObjXObject>("InstObj") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/jwxini.cpp b/engines/director/lingo/xlibs/jwxini.cpp
index bb88b8e0cec..a802c7ab315 100644
--- a/engines/director/lingo/xlibs/jwxini.cpp
+++ b/engines/director/lingo/xlibs/jwxini.cpp
@@ -82,7 +82,7 @@ void JourneyWareXINIXObj::close(ObjectType type) {
}
-JourneyWareXINIXObject::JourneyWareXINIXObject(ObjectType ObjectType) :Object<JourneyWareXINIXObject>("JourneyWareXINIXObj") {
+JourneyWareXINIXObject::JourneyWareXINIXObject(ObjectType ObjectType) :Object<JourneyWareXINIXObject>("INI") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/maniacbg.cpp b/engines/director/lingo/xlibs/maniacbg.cpp
index 8b74b51fd45..c35353ac118 100644
--- a/engines/director/lingo/xlibs/maniacbg.cpp
+++ b/engines/director/lingo/xlibs/maniacbg.cpp
@@ -45,7 +45,7 @@ I mIsForeMost --Is this Application foremost. 1=Yes, 0=No.
namespace Director {
-const char *ManiacBgXObj::xlibName = "foremost";
+const char *ManiacBgXObj::xlibName = "ForeMost";
const char *ManiacBgXObj::fileNames[] = {
"maniacbg",
nullptr
@@ -58,7 +58,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-ManiacBgXObject::ManiacBgXObject(ObjectType ObjectType) :Object<ManiacBgXObject>("ManiacBgXObj") {
+ManiacBgXObject::ManiacBgXObject(ObjectType ObjectType) :Object<ManiacBgXObject>("ForeMost") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/mapnavigatorxobj.cpp b/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
index 90317c3d3e7..e38e826132c 100644
--- a/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
+++ b/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
@@ -80,7 +80,7 @@ SIIII mGetInstruction, node, hotspot, condition, i -- return ith instruction
namespace Director {
-const char *MapNavigatorXObj::xlibName = "mapnavigatorxobj";
+const char *MapNavigatorXObj::xlibName = "MapNav";
const char *MapNavigatorXObj::fileNames[] = {
"MAPNAV", // Jewels of the Oracle - Win
"MapNavigator.XObj", // Jewels of the Oracle - Mac
@@ -109,7 +109,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-MapNavigatorXObject::MapNavigatorXObject(ObjectType ObjectType) :Object<MapNavigatorXObject>("MapNavigatorXObj") {
+MapNavigatorXObject::MapNavigatorXObject(ObjectType ObjectType) :Object<MapNavigatorXObject>("MapNav") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/memcheckxobj.cpp b/engines/director/lingo/xlibs/memcheckxobj.cpp
index 943222e84c4..074548b756f 100644
--- a/engines/director/lingo/xlibs/memcheckxobj.cpp
+++ b/engines/director/lingo/xlibs/memcheckxobj.cpp
@@ -52,7 +52,7 @@ X mMemoryPurge -- Clear chunk o' mem
namespace Director {
-const char *MemCheckXObj::xlibName = "memcheckxobj";
+const char *MemCheckXObj::xlibName = "MemCheck";
const char *MemCheckXObj::fileNames[] = {
"MemCheck", // Jewels of the Oracle - Win
"MemCheck.XObj", // Jewels of the Oracle - Mac
@@ -67,7 +67,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-MemCheckXObject::MemCheckXObject(ObjectType ObjectType) :Object<MemCheckXObject>("MemCheckXObj") {
+MemCheckXObject::MemCheckXObject(ObjectType ObjectType) :Object<MemCheckXObject>("MemCheck") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/memoryxobj.cpp b/engines/director/lingo/xlibs/memoryxobj.cpp
index 1ff36ac88a8..bca5b00b587 100644
--- a/engines/director/lingo/xlibs/memoryxobj.cpp
+++ b/engines/director/lingo/xlibs/memoryxobj.cpp
@@ -96,7 +96,7 @@ void MemoryXObj::close(ObjectType type) {
}
-MemoryXObject::MemoryXObject(ObjectType ObjectType) :Object<MemoryXObject>("MemoryXObj") {
+MemoryXObject::MemoryXObject(ObjectType ObjectType) :Object<MemoryXObject>("Memory") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/mmovie.cpp b/engines/director/lingo/xlibs/mmovie.cpp
index 34dd0dbd1ef..4842e862644 100644
--- a/engines/director/lingo/xlibs/mmovie.cpp
+++ b/engines/director/lingo/xlibs/mmovie.cpp
@@ -108,7 +108,7 @@ static BuiltinProto xlibBuiltins[] = {
{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
};
-MMovieXObject::MMovieXObject(ObjectType ObjectType) :Object<MMovieXObject>("MMovieXObj") {
+MMovieXObject::MMovieXObject(ObjectType ObjectType) :Object<MMovieXObject>("MMovie") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/movemousexobj.cpp b/engines/director/lingo/xlibs/movemousexobj.cpp
index 5c1a5b77f8b..83c2dcb7c7a 100644
--- a/engines/director/lingo/xlibs/movemousexobj.cpp
+++ b/engines/director/lingo/xlibs/movemousexobj.cpp
@@ -54,7 +54,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-MoveMouseXObject::MoveMouseXObject(ObjectType ObjectType) :Object<MoveMouseXObject>("MoveMouseXObj") {
+MoveMouseXObject::MoveMouseXObject(ObjectType ObjectType) :Object<MoveMouseXObject>("MoveMouse") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/movieidxxobj.cpp b/engines/director/lingo/xlibs/movieidxxobj.cpp
index c2ce6b4fec7..6c410203f45 100644
--- a/engines/director/lingo/xlibs/movieidxxobj.cpp
+++ b/engines/director/lingo/xlibs/movieidxxobj.cpp
@@ -50,7 +50,7 @@ SS mMovieInfo -- return info given name
namespace Director {
-const char *MovieIdxXObj::xlibName = "movieidxxobj";
+const char *MovieIdxXObj::xlibName = "MovieIdx";
const char *MovieIdxXObj::fileNames[] = {
"MovieIdx", // Jewels of the Oracle - Win
"MovieIdx.XObj", // Jewels of the Oracle - Mac
@@ -64,7 +64,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-MovieIdxXObject::MovieIdxXObject(ObjectType ObjectType) :Object<MovieIdxXObject>("MovieIdxXObj") {
+MovieIdxXObject::MovieIdxXObject(ObjectType ObjectType) :Object<MovieIdxXObject>("MovieIdx") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/movutils.cpp b/engines/director/lingo/xlibs/movutils.cpp
index 61964d48c48..b730198d2a7 100644
--- a/engines/director/lingo/xlibs/movutils.cpp
+++ b/engines/director/lingo/xlibs/movutils.cpp
@@ -140,7 +140,7 @@ void MovUtilsXObj::close(ObjectType type) {
}
}
-MovieUtilsXObject::MovieUtilsXObject(ObjectType ObjectType) :Object<MovieUtilsXObject>("MovUtilsXObj") {
+MovieUtilsXObject::MovieUtilsXObject(ObjectType ObjectType) :Object<MovieUtilsXObject>("MovUtils") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/paco.cpp b/engines/director/lingo/xlibs/paco.cpp
index 6fbfc7c7312..67a19a8ad67 100644
--- a/engines/director/lingo/xlibs/paco.cpp
+++ b/engines/director/lingo/xlibs/paco.cpp
@@ -66,7 +66,7 @@ static BuiltinProto xlibBuiltins[] = {
{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
};
-PACoXObject::PACoXObject(ObjectType ObjectType) :Object<PACoXObject>("PACoXObj") {
+PACoXObject::PACoXObject(ObjectType ObjectType) :Object<PACoXObject>("PACo") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/palxobj.cpp b/engines/director/lingo/xlibs/palxobj.cpp
index 42cda592eb6..3c2735b76a1 100644
--- a/engines/director/lingo/xlibs/palxobj.cpp
+++ b/engines/director/lingo/xlibs/palxobj.cpp
@@ -86,7 +86,7 @@ void PalXObj::close(ObjectType type) {
}
-PalXObject::PalXObject(ObjectType ObjectType) :Object<PalXObject>("PalXObj") {
+PalXObject::PalXObject(ObjectType ObjectType) :Object<PalXObject>("FixPalette") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/panel.cpp b/engines/director/lingo/xlibs/panel.cpp
index 4b57ef50917..daf49161dc0 100644
--- a/engines/director/lingo/xlibs/panel.cpp
+++ b/engines/director/lingo/xlibs/panel.cpp
@@ -90,7 +90,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-PanelXObject::PanelXObject(ObjectType ObjectType) :Object<PanelXObject>("PanelXObj") {
+PanelXObject::PanelXObject(ObjectType ObjectType) :Object<PanelXObject>("Panel") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/printomatic.cpp b/engines/director/lingo/xlibs/printomatic.cpp
index 23544d3d99a..616002a93b2 100644
--- a/engines/director/lingo/xlibs/printomatic.cpp
+++ b/engines/director/lingo/xlibs/printomatic.cpp
@@ -77,8 +77,8 @@ V mStrokedOval [, left, top, right, bottom | , centerH, centerV, radius ]
V mFilledOval [, left, top, right, bottom | , centerH, centerV, radius ]
XIIII mLine, startH, startV, endH, endV
V mPicture, pict | pictFile | pictResID, left, top [ , right, bottom ]
-V mStagePicture, left, top , right, bottom [,clipLeft ,clipTop ...]
-V m1BitStagePicture, left, top , right, bottom [,clipLeft ,clipTop ...]
+V mStagePicture, left, top , right, bottom [,clipLeft ,clipTop ...]
+V m1BitStagePicture, left, top , right, bottom [,clipLeft ,clipTop ...]
V mEPSFile, fileName, left, top , right, bottom
--
-- PRINTING
@@ -157,7 +157,7 @@ void PrintOMaticXObj::close(ObjectType type) {
}
-PrintOMaticXObject::PrintOMaticXObject(ObjectType ObjectType) :Object<PrintOMaticXObject>("PrintOMaticXObj") {
+PrintOMaticXObject::PrintOMaticXObject(ObjectType ObjectType) :Object<PrintOMaticXObject>("PrintOMatic") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
index 320e85c3a35..fdf482d9605 100644
--- a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
+++ b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
@@ -52,7 +52,7 @@ XIIIIIIIIS mPlay, filesOffset, startTime, duration, interruptable, h, v, hideCur
namespace Director {
-const char *QTCatMoviePlayerXObj::xlibName = "qtcatmovieplayerxobj";
+const char *QTCatMoviePlayerXObj::xlibName = "CatPlayr";
const char *QTCatMoviePlayerXObj::fileNames[] = {
"CATPLAYR", // Jewels of the Oracle - Win
"QTCatMoviePlayer.XObj", // Jewels of the Oracle - Mac
@@ -66,7 +66,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-QTCatMoviePlayerXObject::QTCatMoviePlayerXObject(ObjectType ObjectType) :Object<QTCatMoviePlayerXObject>("QTCatMoviePlayerXObj") {
+QTCatMoviePlayerXObject::QTCatMoviePlayerXObject(ObjectType ObjectType) :Object<QTCatMoviePlayerXObject>("CatPlayr") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/stagetc.cpp b/engines/director/lingo/xlibs/stagetc.cpp
index 3899b71fac0..65feb123c66 100644
--- a/engines/director/lingo/xlibs/stagetc.cpp
+++ b/engines/director/lingo/xlibs/stagetc.cpp
@@ -69,7 +69,7 @@ void StageTCXObj::close(ObjectType type) {
}
-StageTCXObject::StageTCXObject(ObjectType ObjectType) :Object<StageTCXObject>("StageTCXObj") {
+StageTCXObject::StageTCXObject(ObjectType ObjectType) :Object<StageTCXObject>("StageTC") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/valkyrie.cpp b/engines/director/lingo/xlibs/valkyrie.cpp
index 56a82706ade..d73f91f687f 100644
--- a/engines/director/lingo/xlibs/valkyrie.cpp
+++ b/engines/director/lingo/xlibs/valkyrie.cpp
@@ -81,7 +81,7 @@ void ValkyrieXObj::close(ObjectType type) {
}
-ValkyrieXObject::ValkyrieXObject(ObjectType ObjectType) :Object<ValkyrieXObject>("ValkyrieXObj") {
+ValkyrieXObject::ValkyrieXObject(ObjectType ObjectType) :Object<ValkyrieXObject>("Valkyrie") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/widgetxobj.cpp b/engines/director/lingo/xlibs/widgetxobj.cpp
index 309ddbdce88..f0cea08a78c 100644
--- a/engines/director/lingo/xlibs/widgetxobj.cpp
+++ b/engines/director/lingo/xlibs/widgetxobj.cpp
@@ -45,7 +45,7 @@
namespace Director {
-const char *WidgetXObj::xlibName = "widget";
+const char *WidgetXObj::xlibName = "Widget";
const char *WidgetXObj::fileNames[] = {
"widget",
nullptr
@@ -74,7 +74,7 @@ void WidgetXObj::close(ObjectType type) {
}
}
-WidgetXObject::WidgetXObject(ObjectType ObjectType) :Object<WidgetXObject>("WidgetXObj") {
+WidgetXObject::WidgetXObject(ObjectType ObjectType) :Object<WidgetXObject>("Widget") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/window.cpp b/engines/director/lingo/xlibs/window.cpp
index 1dfc7a7d522..5767e1b012a 100644
--- a/engines/director/lingo/xlibs/window.cpp
+++ b/engines/director/lingo/xlibs/window.cpp
@@ -103,7 +103,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-WindowXObject::WindowXObject(ObjectType ObjectType) :Object<WindowXObject>("WindowXObj") {
+WindowXObject::WindowXObject(ObjectType ObjectType) :Object<WindowXObject>("Window") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/wininfo.cpp b/engines/director/lingo/xlibs/wininfo.cpp
index 506bcb027e0..96545acbdaa 100644
--- a/engines/director/lingo/xlibs/wininfo.cpp
+++ b/engines/director/lingo/xlibs/wininfo.cpp
@@ -45,7 +45,7 @@ SSSS mWinInfo, file, section, entry --Returns Windows information item
namespace Director {
-const char *WinInfoXObj::xlibName = "wininfo";
+const char *WinInfoXObj::xlibName = "Wininfo";
const char *WinInfoXObj::fileNames[] = {
"wininfo",
nullptr
@@ -59,7 +59,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-WinInfoXObject::WinInfoXObject(ObjectType ObjectType) : Object<WinInfoXObject>("WinInfoXObj") {
+WinInfoXObject::WinInfoXObject(ObjectType ObjectType) : Object<WinInfoXObject>("Wininfo") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/winxobj.cpp b/engines/director/lingo/xlibs/winxobj.cpp
index 8394e9b0ce7..099335ae5ea 100644
--- a/engines/director/lingo/xlibs/winxobj.cpp
+++ b/engines/director/lingo/xlibs/winxobj.cpp
@@ -263,7 +263,7 @@ void RearWindowXObj::close(ObjectType type) {
}
-RearWindowXObject::RearWindowXObject(ObjectType ObjectType) :Object<RearWindowXObject>("RearWindowXObj") {
+RearWindowXObject::RearWindowXObject(ObjectType ObjectType) :Object<RearWindowXObject>("RearWindow") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/xcmdglue.cpp b/engines/director/lingo/xlibs/xcmdglue.cpp
index 0c83190caf8..97f58cc43f1 100644
--- a/engines/director/lingo/xlibs/xcmdglue.cpp
+++ b/engines/director/lingo/xlibs/xcmdglue.cpp
@@ -67,7 +67,7 @@ static MethodProto xlibMethods[] = {
{ nullptr, nullptr, 0, 0, 0 }
};
-XCMDGlueXObject::XCMDGlueXObject(ObjectType ObjectType) :Object<XCMDGlueXObject>("XCMDGlueXObj") {
+XCMDGlueXObject::XCMDGlueXObject(ObjectType ObjectType) :Object<XCMDGlueXObject>("XCMDGlue") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/xio.cpp b/engines/director/lingo/xlibs/xio.cpp
index 4254f7e1b43..43c600ecd61 100644
--- a/engines/director/lingo/xlibs/xio.cpp
+++ b/engines/director/lingo/xlibs/xio.cpp
@@ -76,7 +76,7 @@ void XioXObj::close(ObjectType type) {
}
-XioXObject::XioXObject(ObjectType ObjectType) :Object<XioXObject>("XioXObj") {
+XioXObject::XioXObject(ObjectType ObjectType) :Object<XioXObject>("Xio") {
_objType = ObjectType;
}
diff --git a/engines/director/lingo/xlibs/xwin.cpp b/engines/director/lingo/xlibs/xwin.cpp
index 60fd8ff627f..f935a8c593d 100644
--- a/engines/director/lingo/xlibs/xwin.cpp
+++ b/engines/director/lingo/xlibs/xwin.cpp
@@ -97,7 +97,7 @@ static BuiltinProto xlibBuiltins[] = {
{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
};
-XWINXObject::XWINXObject(ObjectType ObjectType) :Object<XWINXObject>("XWINXObj") {
+XWINXObject::XWINXObject(ObjectType ObjectType) :Object<XWINXObject>("XWIN") {
_objType = ObjectType;
}
Commit: 616b63aa8f8423ba395394b43f3bdeb3ccadf57d
https://github.com/scummvm/scummvm/commit/616b63aa8f8423ba395394b43f3bdeb3ccadf57d
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: XOBJ: Add drive type detection to InstObj
Changed paths:
engines/director/lingo/xlibs/instobj.cpp
diff --git a/engines/director/lingo/xlibs/instobj.cpp b/engines/director/lingo/xlibs/instobj.cpp
index 0fda4aa93c5..974264d5d6e 100644
--- a/engines/director/lingo/xlibs/instobj.cpp
+++ b/engines/director/lingo/xlibs/instobj.cpp
@@ -120,6 +120,33 @@ void InstObjXObj::m_new(int nargs) {
g_lingo->push(g_lingo->_state->me);
}
+void InstObjXObj::m_getDriveType(int nargs) {
+ g_lingo->printSTUBWithArglist("InstObjXObj::m_getDriveType", nargs);
+ Datum result("Undetermined Drive Type");
+
+ if (nargs == 1) {
+ warning("InstObjXObj: expected 1 argument");
+ g_lingo->dropStack(nargs);
+ } else {
+ Datum id = g_lingo->pop();
+ switch (id.asInt()) {
+ case 1: // fall-through
+ case 2:
+ result = Datum("Floppy Drive");
+ break;
+ case 3:
+ result = Datum("Hard Disk");
+ break;
+ case 4:
+ result = Datum("CD Drive");
+ break;
+ default:
+ break;
+ }
+ }
+ g_lingo->push(result);
+}
+
XOBJSTUBNR(InstObjXObj::m_dispose)
XOBJSTUB(InstObjXObj::m_name, "")
XOBJSTUB(InstObjXObj::m_status, 0)
@@ -129,7 +156,6 @@ XOBJSTUB(InstObjXObj::m_getWinDir, "")
XOBJSTUB(InstObjXObj::m_getSysDir, "")
XOBJSTUB(InstObjXObj::m_getWinVer, "")
XOBJSTUB(InstObjXObj::m_getProcInfo, "")
-XOBJSTUB(InstObjXObj::m_getDriveType, "")
XOBJSTUB(InstObjXObj::m_getFreeSpace, 0)
XOBJSTUB(InstObjXObj::m_makeDir, 0)
XOBJSTUB(InstObjXObj::m_dirExists, 0)
Commit: 54c6bd26363a468f88ced71ddcc77086b99448ee
https://github.com/scummvm/scummvm/commit/54c6bd26363a468f88ced71ddcc77086b99448ee
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Add framework for duplicating cast members
Changed paths:
engines/director/cast.cpp
engines/director/cast.h
engines/director/castmember/bitmap.cpp
engines/director/castmember/bitmap.h
engines/director/castmember/digitalvideo.cpp
engines/director/castmember/digitalvideo.h
engines/director/castmember/filmloop.cpp
engines/director/castmember/filmloop.h
engines/director/castmember/movie.cpp
engines/director/castmember/movie.h
engines/director/castmember/palette.cpp
engines/director/castmember/palette.h
engines/director/castmember/script.cpp
engines/director/castmember/script.h
engines/director/castmember/shape.cpp
engines/director/castmember/shape.h
engines/director/castmember/sound.cpp
engines/director/castmember/sound.h
engines/director/castmember/text.cpp
engines/director/castmember/text.h
engines/director/castmember/transition.cpp
engines/director/castmember/transition.h
engines/director/lingo/lingo-builtins.cpp
engines/director/movie.cpp
engines/director/movie.h
engines/director/score.cpp
engines/director/score.h
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index a0a35cbe753..54c607f8fa5 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -195,6 +195,14 @@ int Cast::getCastMaxID() {
return result;
}
+int Cast::getNextUnusedID() {
+ int result = 1;
+ while (_loadedCast->contains(result)) {
+ result += 1;
+ }
+ return result;
+}
+
Common::Rect Cast::getCastMemberInitialRect(int castId) {
CastMember *cast = _loadedCast->getVal(castId);
@@ -217,20 +225,67 @@ void Cast::setCastMemberModified(int castId) {
cast->setModified(true);
}
-CastMember *Cast::setCastMember(CastMemberID castId, CastMember *cast) {
- if (_loadedCast->contains(castId.member)) {
- _loadedCast->erase(castId.member);
+CastMember *Cast::setCastMember(int castId, CastMember *cast) {
+ if (_loadedCast->contains(castId)) {
+ _loadedCast->erase(castId);
}
- _loadedCast->setVal(castId.member, cast);
+ _loadedCast->setVal(castId, cast);
return cast;
}
-bool Cast::eraseCastMember(CastMemberID castId) {
- if (_loadedCast->contains(castId.member)) {
- CastMember *member = _loadedCast->getVal(castId.member);
+bool Cast::duplicateCastMember(CastMember *source, int targetId) {
+ if (_loadedCast->contains(targetId)) {
+ eraseCastMember(targetId);
+ }
+ // duplicating a cast member with a non-existent source
+ // is the same as deleting the target
+ if (!source)
+ return true;
+ CastMember *target = nullptr;
+ switch (source->_type) {
+ case kCastBitmap:
+ target = (CastMember *)(new BitmapCastMember(this, targetId, *(BitmapCastMember *)source));
+ break;
+ case kCastDigitalVideo:
+ target = (CastMember *)(new DigitalVideoCastMember(this, targetId, *(DigitalVideoCastMember *)source));
+ break;
+ case kCastFilmLoop:
+ target = (CastMember *)(new FilmLoopCastMember(this, targetId, *(FilmLoopCastMember *)source));
+ break;
+ case kCastMovie:
+ target = (CastMember *)(new MovieCastMember(this, targetId, *(MovieCastMember *)source));
+ break;
+ case kCastPalette:
+ target = (CastMember *)(new PaletteCastMember(this, targetId, *(PaletteCastMember *)source));
+ break;
+ case kCastLingoScript:
+ target = (CastMember *)(new ScriptCastMember(this, targetId, *(ScriptCastMember *)source));
+ break;
+ case kCastShape:
+ target = (CastMember *)(new ShapeCastMember(this, targetId, *(ShapeCastMember *)source));
+ break;
+ case kCastText:
+ target = (CastMember *)(new TextCastMember(this, targetId, *(TextCastMember *)source));
+ break;
+ case kCastTransition:
+ target = (CastMember *)(new TransitionCastMember(this, targetId, *(TransitionCastMember *)source));
+ break;
+ default:
+ warning("Cast::duplicateCastMember(): unsupported cast type %s", castType2str(source->_type));
+ return false;
+ break;
+ }
+
+ setCastMember(targetId, target);
+ return true;
+}
+
+bool Cast::eraseCastMember(int castId) {
+ if (_loadedCast->contains(castId)) {
+ CastMember *member = _loadedCast->getVal(castId);
delete member;
- _loadedCast->erase(castId.member);
+ _loadedCast->erase(castId);
return true;
}
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 42ded68237d..7933ce4ceb8 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -99,10 +99,12 @@ public:
int getCastSize();
int getCastMaxID();
+ int getNextUnusedID();
Common::Rect getCastMemberInitialRect(int castId);
void setCastMemberModified(int castId);
- CastMember *setCastMember(CastMemberID castId, CastMember *cast);
- bool eraseCastMember(CastMemberID castId);
+ CastMember *setCastMember(int castId, CastMember *cast);
+ bool duplicateCastMember(CastMember *source, int targetId);
+ bool eraseCastMember(int castId);
CastMember *getCastMember(int castId, bool load = true);
CastMember *getCastMemberByNameAndType(const Common::String &name, CastType type);
CastMember *getCastMemberByScriptId(int scriptId);
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index f7803311d0f..779c236f9c8 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -179,6 +179,34 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Image::ImageDecode
_external = false;
}
+BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, BitmapCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastBitmap;
+ // force a load so we can copy the cast resource information
+ source.load();
+ _loaded = true;
+
+ _picture = source._picture ? new Picture(*source._picture) : nullptr;
+ _ditheredImg = nullptr;
+ _matte = nullptr;
+
+ _pitch = source._pitch;
+ _regX = source._regX;
+ _regY = source._regY;
+ _flags2 = source._regY;
+ _bytes = source._bytes;
+ _clut = source._clut;
+ _ditheredTargetClut = source._ditheredTargetClut;
+
+ _bitsPerPixel = source._bitsPerPixel;
+
+ _tag = source._tag;
+ _noMatte = source._noMatte;
+ _external = source._external;
+
+ warning("BitmapCastMember(): Duplicating source %d to target %d! This is unlikely to work properly, as the resource loader is based on the cast ID", source._castId, castId);
+}
+
BitmapCastMember::~BitmapCastMember() {
delete _picture;
diff --git a/engines/director/castmember/bitmap.h b/engines/director/castmember/bitmap.h
index 04121e5e6e7..09139cf4b93 100644
--- a/engines/director/castmember/bitmap.h
+++ b/engines/director/castmember/bitmap.h
@@ -34,7 +34,9 @@ class BitmapCastMember : public CastMember {
public:
BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint32 castTag, uint16 version, uint8 flags1 = 0);
BitmapCastMember(Cast *cast, uint16 castId, Image::ImageDecoder *img, uint8 flags1 = 0);
+ BitmapCastMember(Cast *cast, uint16 castId, BitmapCastMember &source);
~BitmapCastMember();
+
Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
bool isModified() override;
diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index e0f27ded3d0..9087a17f067 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -81,6 +81,38 @@ DigitalVideoCastMember::DigitalVideoCastMember(Cast *cast, uint16 castId, Common
debugC(2, kDebugLoading, "_avimovie: %d, _qtmovie: %d", _avimovie, _qtmovie);
}
+DigitalVideoCastMember::DigitalVideoCastMember(Cast *cast, uint16 castId, DigitalVideoCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastDigitalVideo;
+ _loaded = source._loaded;
+
+ _filename = source._filename;
+
+ _vflags = source._vflags;
+ _looping = source._looping;
+ _pausedAtStart = source._pausedAtStart;
+ _enableVideo = source._enableVideo;
+ _enableSound = source._enableSound;
+ _crop = source._crop;
+ _center = source._center;
+ _preload = source._preload;
+ _showControls = source._showControls;
+ _directToStage = source._directToStage;
+ _avimovie = source._avimovie;
+ _qtmovie = source._qtmovie;
+ _dirty = source._dirty;
+ _frameRateType = source._frameRateType;
+
+ _frameRate = source._frameRate;
+ _getFirstFrame = source._getFirstFrame;
+ _duration = source._duration;
+
+ _video = nullptr;
+ _lastFrame = nullptr;
+
+ _channel = nullptr;
+}
+
DigitalVideoCastMember::~DigitalVideoCastMember() {
if (_lastFrame) {
_lastFrame->free();
diff --git a/engines/director/castmember/digitalvideo.h b/engines/director/castmember/digitalvideo.h
index ab7397e2939..2eccf7de934 100644
--- a/engines/director/castmember/digitalvideo.h
+++ b/engines/director/castmember/digitalvideo.h
@@ -33,6 +33,7 @@ namespace Director {
class DigitalVideoCastMember : public CastMember {
public:
DigitalVideoCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ DigitalVideoCastMember(Cast *cast, uint16 castId, DigitalVideoCastMember &source);
~DigitalVideoCastMember();
bool isModified() override;
diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index c771a63ef5c..2a842fc4da9 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -47,6 +47,19 @@ FilmLoopCastMember::FilmLoopCastMember(Cast *cast, uint16 castId, Common::Seekab
_center = false;
}
+FilmLoopCastMember::FilmLoopCastMember(Cast *cast, uint16 castId, FilmLoopCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastFilmLoop;
+ // force a load so we can copy the cast resource information
+ source.load();
+ _loaded = true;
+ _enableSound = source._enableSound;
+ _crop = source._crop;
+ _center = source._center;
+ _frames = source._frames;
+ _subchannels = source._subchannels;
+}
+
FilmLoopCastMember::~FilmLoopCastMember() {
}
diff --git a/engines/director/castmember/filmloop.h b/engines/director/castmember/filmloop.h
index d78efad226f..3f6c6c98ebc 100644
--- a/engines/director/castmember/filmloop.h
+++ b/engines/director/castmember/filmloop.h
@@ -35,6 +35,7 @@ struct FilmLoopFrame {
class FilmLoopCastMember : public CastMember {
public:
FilmLoopCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ FilmLoopCastMember(Cast *cast, uint16 castId, FilmLoopCastMember &source);
~FilmLoopCastMember();
bool isModified() override;
diff --git a/engines/director/castmember/movie.cpp b/engines/director/castmember/movie.cpp
index 38026310f8d..5e326188f50 100644
--- a/engines/director/castmember/movie.cpp
+++ b/engines/director/castmember/movie.cpp
@@ -46,6 +46,19 @@ MovieCastMember::MovieCastMember(Cast *cast, uint16 castId, Common::SeekableRead
}
+MovieCastMember::MovieCastMember(Cast *cast, uint16 castId, MovieCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastMovie;
+ _loaded = source._loaded;
+
+ _flags = source._flags;
+ _looping = source._looping;
+ _enableScripts = source._enableScripts;
+ _enableSound = source._enableSound;
+ _crop = source._crop;
+ _center = source._center;
+}
+
Common::String MovieCastMember::formatInfo() {
return Common::String::format(
"initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, enableScripts: %d, enableSound: %d, looping: %d, crop: %d, center: %d",
diff --git a/engines/director/castmember/movie.h b/engines/director/castmember/movie.h
index 31d3322f1a9..ac4f293379c 100644
--- a/engines/director/castmember/movie.h
+++ b/engines/director/castmember/movie.h
@@ -29,6 +29,7 @@ namespace Director {
class MovieCastMember : public CastMember {
public:
MovieCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ MovieCastMember(Cast *cast, uint16 castId, MovieCastMember &source);
Common::String formatInfo() override;
diff --git a/engines/director/castmember/palette.cpp b/engines/director/castmember/palette.cpp
index 32bdf7409eb..027069ea297 100644
--- a/engines/director/castmember/palette.cpp
+++ b/engines/director/castmember/palette.cpp
@@ -31,6 +31,16 @@ PaletteCastMember::PaletteCastMember(Cast *cast, uint16 castId, Common::Seekable
_palette = nullptr;
}
+PaletteCastMember::PaletteCastMember(Cast *cast, uint16 castId, PaletteCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastPalette;
+ // force a load so we can copy the cast resource information
+ source.load();
+ _loaded = true;
+
+ _palette = source._palette ? new PaletteV4(*source._palette) : nullptr;
+}
+
Common::String PaletteCastMember::formatInfo() {
Common::String result;
if (_palette) {
diff --git a/engines/director/castmember/palette.h b/engines/director/castmember/palette.h
index 45524a4f74b..43f44b61ea4 100644
--- a/engines/director/castmember/palette.h
+++ b/engines/director/castmember/palette.h
@@ -29,6 +29,7 @@ namespace Director {
class PaletteCastMember : public CastMember {
public:
PaletteCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ PaletteCastMember(Cast *cast, uint16 castId, PaletteCastMember &source);
CastMemberID getPaletteId() { return _palette ? _palette->id : CastMemberID(0, 0); }
void activatePalette() { if (_palette) g_director->setPalette(_palette->id); }
diff --git a/engines/director/castmember/script.cpp b/engines/director/castmember/script.cpp
index ccd7d2eefa7..7c190c2df90 100644
--- a/engines/director/castmember/script.cpp
+++ b/engines/director/castmember/script.cpp
@@ -64,6 +64,13 @@ ScriptCastMember::ScriptCastMember(Cast *cast, uint16 castId, Common::SeekableRe
}
}
+ScriptCastMember::ScriptCastMember(Cast *cast, uint16 castId, ScriptCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastLingoScript;
+ _scriptType = source._scriptType;
+ warning("ScriptCastMember(): Duplicating source %d to target %d! This is unlikely to work properly, as the actual scripts aren't yet copied", source._castId, castId);
+}
+
Common::String ScriptCastMember::formatInfo() {
return Common::String::format(
"scriptType: %s", scriptType2str(_scriptType)
diff --git a/engines/director/castmember/script.h b/engines/director/castmember/script.h
index bcaccd694d3..a9f12a69504 100644
--- a/engines/director/castmember/script.h
+++ b/engines/director/castmember/script.h
@@ -29,6 +29,7 @@ namespace Director {
class ScriptCastMember : public CastMember {
public:
ScriptCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ ScriptCastMember(Cast *cast, uint16 castId, ScriptCastMember &source);
ScriptType _scriptType;
diff --git a/engines/director/castmember/shape.cpp b/engines/director/castmember/shape.cpp
index c5a3ec1f86f..ab14751813f 100644
--- a/engines/director/castmember/shape.cpp
+++ b/engines/director/castmember/shape.cpp
@@ -80,6 +80,19 @@ ShapeCastMember::ShapeCastMember(Cast *cast, uint16 castId, Common::SeekableRead
_initialRect.debugPrint(0, "ShapeCastMember: rect:");
}
+ShapeCastMember::ShapeCastMember(Cast *cast, uint16 castId, ShapeCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastShape;
+ _loaded = source._loaded;
+
+ _shapeType = source._shapeType;
+ _pattern = source._pattern;
+ _fillType = source._fillType;
+ _lineThickness = source._lineThickness;
+ _lineDirection = source._lineDirection;
+ _ink = source._ink;
+}
+
void ShapeCastMember::setBackColor(uint32 bgCol) {
_bgCol = bgCol;
_modified = true;
diff --git a/engines/director/castmember/shape.h b/engines/director/castmember/shape.h
index 2f1eb3d9efd..5e733d46256 100644
--- a/engines/director/castmember/shape.h
+++ b/engines/director/castmember/shape.h
@@ -29,6 +29,7 @@ namespace Director {
class ShapeCastMember : public CastMember {
public:
ShapeCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ ShapeCastMember(Cast *cast, uint16 castId, ShapeCastMember &source);
uint32 getForeColor() override { return _fgCol; }
uint32 getBackColor() override { return _bgCol; }
void setBackColor(uint32 bgCol) override;
diff --git a/engines/director/castmember/sound.cpp b/engines/director/castmember/sound.cpp
index 892f0922977..8eb3916f082 100644
--- a/engines/director/castmember/sound.cpp
+++ b/engines/director/castmember/sound.cpp
@@ -33,6 +33,15 @@ SoundCastMember::SoundCastMember(Cast *cast, uint16 castId, Common::SeekableRead
_looping = 0;
}
+SoundCastMember::SoundCastMember(Cast *cast, uint16 castId, SoundCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastSound;
+ _loaded = false;
+ _audio = nullptr;
+ _looping = source._looping;
+ warning("SoundCastMember(): Duplicating source %d to target %d! This is unlikely to work properly, as the resource loader is based on the cast ID", source._castId, castId);
+}
+
SoundCastMember::~SoundCastMember() {
if (_audio)
delete _audio;
diff --git a/engines/director/castmember/sound.h b/engines/director/castmember/sound.h
index f4b7527b493..afb1fcad63e 100644
--- a/engines/director/castmember/sound.h
+++ b/engines/director/castmember/sound.h
@@ -31,6 +31,7 @@ class AudioDecoder;
class SoundCastMember : public CastMember {
public:
SoundCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ SoundCastMember(Cast *cast, uint16 castId, SoundCastMember &source);
~SoundCastMember();
void load() override;
diff --git a/engines/director/castmember/text.cpp b/engines/director/castmember/text.cpp
index 668965e36fd..346ec0da44f 100644
--- a/engines/director/castmember/text.cpp
+++ b/engines/director/castmember/text.cpp
@@ -182,6 +182,45 @@ TextCastMember::TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadSt
_modified = true;
}
+TextCastMember::TextCastMember(Cast *cast, uint16 castId, TextCastMember &source)
+ : CastMember(cast, castId) {
+ _type = kCastText;
+ // force a load so we can copy the cast resource information
+ source.load();
+ _loaded = true;
+
+ _borderSize = source._borderSize;
+ _gutterSize = source._gutterSize;
+ _boxShadow = source._boxShadow;
+ _maxHeight = source._maxHeight;
+ _textHeight = source._textHeight;
+
+ _fontId = source._fontId;
+ _fontSize = source._fontSize;
+ _textType = source._textType;
+ _textAlign = source._textAlign;
+ _textShadow = source._textShadow;
+ _scroll = source._scroll;
+ _textSlant = source._textSlant;
+ _textFlags = source._textFlags;
+ _bgpalinfo1 = source._bgpalinfo1;
+ _bgpalinfo2 = source._bgpalinfo2;
+ _bgpalinfo3 = source._bgpalinfo3;
+ _fgpalinfo1 = source._fgpalinfo1;
+ _fgpalinfo2 = source._fgpalinfo2;
+ _fgpalinfo3 = source._fgpalinfo3;
+ _buttonType = source._buttonType;
+ _editable = source._editable;
+ _lineSpacing = source._lineSpacing;
+
+ _ftext = source._ftext;
+ _ptext = source._ptext;
+ _rtext = source._rtext;
+
+ _bgcolor = source._bgcolor;
+ _fgcolor = source._fgcolor;
+}
+
void TextCastMember::setColors(uint32 *fgcolor, uint32 *bgcolor) {
if (fgcolor)
_fgcolor = *fgcolor;
diff --git a/engines/director/castmember/text.h b/engines/director/castmember/text.h
index 66ed04c976c..4a8e4a94d1c 100644
--- a/engines/director/castmember/text.h
+++ b/engines/director/castmember/text.h
@@ -29,6 +29,7 @@ namespace Director {
class TextCastMember : public CastMember {
public:
TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version, uint8 flags1 = 0, bool asButton = false);
+ TextCastMember(Cast *cast, uint16 castId, TextCastMember &source);
void setColors(uint32 *fgcolor, uint32 *bgcolor) override;
Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
diff --git a/engines/director/castmember/transition.cpp b/engines/director/castmember/transition.cpp
index b7913b89508..ff6b120a866 100644
--- a/engines/director/castmember/transition.cpp
+++ b/engines/director/castmember/transition.cpp
@@ -51,6 +51,17 @@ TransitionCastMember::TransitionCastMember(Cast *cast, uint16 castId, Common::Se
}
}
+TransitionCastMember::TransitionCastMember(Cast *cast, uint16 castId, TransitionCastMember &source)
+ : CastMember(cast, castId) {
+ _transType = source._transType;
+ _loaded = source._loaded;
+
+ _durationMillis = source._durationMillis;
+ _flags = source._flags;
+ _chunkSize = source._chunkSize;
+ _area = source._area;
+}
+
Common::String TransitionCastMember::formatInfo() {
return Common::String::format("transType: %d, durationMillis: %d, flags: %d, chunkSize: %d", _transType, _durationMillis, _flags, _chunkSize);
}
diff --git a/engines/director/castmember/transition.h b/engines/director/castmember/transition.h
index c6f5d859510..63f6a5e761e 100644
--- a/engines/director/castmember/transition.h
+++ b/engines/director/castmember/transition.h
@@ -29,6 +29,7 @@ namespace Director {
class TransitionCastMember : public CastMember {
public:
TransitionCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
+ TransitionCastMember(Cast *cast, uint16 castId, TransitionCastMember &source);
Common::String formatInfo() override;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index e0775a7f7d4..4b9f6713698 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2015,11 +2015,42 @@ void LB::b_copyToClipBoard(int nargs) {
}
void LB::b_duplicate(int nargs) {
- // Removed previous implementation since it copied only the reference to the cast
- // and didn't actually duplicate it.
- // See commit: 76e56f5b1f51a51d073ecf3970134d87964a4ea4
- g_lingo->printSTUBWithArglist("b_duplicate", nargs);
- g_lingo->dropStack(nargs);
+ Datum to;
+ Datum from;
+ Movie *movie = g_director->getCurrentMovie();
+
+ if (nargs >= 2) {
+ nargs -= 2;
+ g_lingo->dropStack(nargs);
+ to = g_lingo->pop();
+ from = g_lingo->pop();
+ if (from.type != CASTREF)
+ error("b_duplicate(): expected CASTREF for from, got %s", from.type2str());
+ if (to.type == INT)
+ to = Datum(CastMemberID(to.asInt(), DEFAULT_CAST_LIB));
+ else if (to.type != CASTREF)
+ error("b_duplicate(): expected CASTREF or INT for to, got %s", to.type2str());
+ } else if (nargs == 1) {
+ // use next available slot in the same cast library
+ from = g_lingo->pop();
+ if (from.type != CASTREF)
+ error("b_duplicate(): expected CASTREF for from, got %s", from.type2str());
+ if (!movie->getCasts()->contains(from.u.cast->castLib))
+ error("b_duplicate(): couldn't find cast lib %d", from.u.cast->castLib);
+
+ Cast *cast = movie->getCasts()->getVal(from.u.cast->castLib);
+ to = Datum(CastMemberID(cast->getNextUnusedID(), from.u.cast->castLib));
+ } else {
+ error("b_duplicate(): expected at least 1 argument");
+ }
+
+ if (!movie->duplicateCastMember(*from.u.cast, *to.u.cast)) {
+ warning("b_duplicate(): failed to copy cast member %s to %s", from.u.cast->asString().c_str(), to.u.cast->asString().c_str());
+ }
+
+ Score *score = movie->getScore();
+ score->refreshPointersForCastMemberID(*to.u.cast);
+ g_lingo->push(Datum(to.u.cast->member));
}
void LB::b_editableText(int nargs) {
@@ -2139,19 +2170,13 @@ void LB::b_importFileInto(int nargs) {
in.close();
Movie *movie = g_director->getCurrentMovie();
+ Score *score = movie->getScore();
BitmapCastMember *bitmapCast = new BitmapCastMember(movie->getCast(), memberID.member, img);
movie->createOrReplaceCastMember(memberID, bitmapCast);
bitmapCast->setModified(true);
const Graphics::Surface *surf = img->getSurface();
bitmapCast->_size = surf->pitch * surf->h + img->getPaletteColorCount() * 3;
- auto channels = movie->getScore()->_channels;
-
- for (uint i = 0; i < channels.size(); i++) {
- if (channels[i]->_sprite->_castId == dst.asMemberID()) {
- channels[i]->setCast(memberID);
- channels[i]->_dirty = true;
- }
- }
+ score->refreshPointersForCastMemberID(dst.asMemberID());
}
void menuCommandsCallback(int action, Common::String &text, void *data) {
@@ -2370,8 +2395,6 @@ void LB::b_move(int nargs) {
b_erase(1);
Score *score = movie->getScore();
uint16 frame = score->getCurrentFrameNum();
- Frame *currentFrame = score->_currentFrame;
- auto channels = score->_channels;
score->renderFrame(frame, kRenderForceUpdate);
@@ -2381,17 +2404,7 @@ void LB::b_move(int nargs) {
movie->createOrReplaceCastMember(dest.asMemberID(), toMove);
movie->createOrReplaceCastMember(src.asMemberID(), toReplace);
- for (uint16 i = 0; i < currentFrame->_sprites.size(); i++) {
- if (currentFrame->_sprites[i]->_castId == dest.asMemberID())
- currentFrame->_sprites[i]->setCast(dest.asMemberID());
- }
-
- for (uint i = 0; i < channels.size(); i++) {
- if (channels[i]->_sprite->_castId == dest.asMemberID()) {
- channels[i]->_sprite->setCast(CastMemberID(1, DEFAULT_CAST_LIB));
- channels[i]->_dirty = true;
- }
- }
+ score->refreshPointersForCastMemberID(dest.asMemberID());
score->renderFrame(frame, kRenderForceUpdate);
}
@@ -2429,23 +2442,9 @@ void LB::b_pasteClipBoardInto(int nargs) {
}
Score *score = movie->getScore();
- Frame *currentFrame = score->_currentFrame;
- auto channels = score->_channels;
-
castMember->setModified(true);
movie->createOrReplaceCastMember(*to.u.cast, castMember);
-
- for (uint16 i = 0; i < currentFrame->_sprites.size(); i++) {
- if (currentFrame->_sprites[i]->_castId == to.asMemberID())
- currentFrame->_sprites[i]->setCast(to.asMemberID());
- }
-
- for (uint i = 0; i < channels.size(); i++) {
- if (channels[i]->_sprite->_castId == to.asMemberID()) {
- channels[i]->_sprite->setCast(to.asMemberID());
- channels[i]->_dirty = true;
- }
- }
+ score->refreshPointersForCastMemberID(to.asMemberID());
}
static const struct PaletteNames {
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 068ea19c588..620a788d972 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -422,9 +422,9 @@ CastMember* Movie::createOrReplaceCastMember(CastMemberID memberID, CastMember*
if (_casts.contains(memberID.castLib)) {
// Delete existing cast member
- _casts.getVal(memberID.castLib)->eraseCastMember(memberID);
+ _casts.getVal(memberID.castLib)->eraseCastMember(memberID.member);
- _casts.getVal(memberID.castLib)->setCastMember(memberID, cast);
+ _casts.getVal(memberID.castLib)->setCastMember(memberID.member, cast);
}
return result;
@@ -432,7 +432,24 @@ CastMember* Movie::createOrReplaceCastMember(CastMemberID memberID, CastMember*
bool Movie::eraseCastMember(CastMemberID memberID) {
if (_casts.contains(memberID.castLib)) {
- return _casts.getVal(memberID.castLib)->eraseCastMember(memberID);
+ return _casts.getVal(memberID.castLib)->eraseCastMember(memberID.member);
+ }
+
+ return false;
+}
+
+bool Movie::duplicateCastMember(CastMemberID source, CastMemberID target) {
+ CastMember *sourceMember = getCastMember(source);
+ if (sourceMember) {
+ if (_casts.contains(target.castLib)) {
+ Cast *cast = _casts.getVal(target.castLib);
+ debugC(3, kDebugLoading, "Movie::DuplicateCastMember(): copying cast data from %s to %s (%s)", source.asString().c_str(), target.asString().c_str(), castType2str(sourceMember->_type));
+ return cast->duplicateCastMember(sourceMember, target.member);
+ } else {
+ warning("Movie::duplicateCastMember(): couldn't find destination castLib %d", target.castLib);
+ }
+ } else {
+ warning("Movie::duplicateCastMember(): couldn't find source cast member %s", source.asString().c_str());
}
return false;
diff --git a/engines/director/movie.h b/engines/director/movie.h
index d8efafa39e7..ffcdcb7ad61 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -110,6 +110,7 @@ public:
CastMember *getCastMember(CastMemberID memberID);
CastMember *createOrReplaceCastMember(CastMemberID memberID, CastMember *cast);
bool eraseCastMember(CastMemberID memberID);
+ bool duplicateCastMember(CastMemberID source, CastMemberID target);
CastMemberID getCastMemberIDByMember(int memberID);
int getCastLibIDByName(const Common::String &name);
CastMemberID getCastMemberIDByName(const Common::String &name);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 1c0873a10a3..88fbfc4167a 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1433,6 +1433,29 @@ uint16 Score::getSpriteIdByMemberId(CastMemberID id) {
return 0;
}
+bool Score::refreshPointersForCastMemberID(CastMemberID id) {
+ // FIXME: This can be removed once Sprite is refactored to not
+ // keep a pointer to a CastMember.
+ bool hit = false;
+ for (auto &it : _channels) {
+ if (it->_sprite->_castId == id) {
+ it->_sprite->_cast = nullptr;
+ it->setCast(id);
+ it->_dirty = true;
+ hit = true;
+ }
+ }
+
+ for (auto &it : _currentFrame->_sprites) {
+ if (it->_castId == id) {
+ it->_cast = nullptr;
+ it->setCast(id);
+ hit = true;
+ }
+ }
+ return hit;
+}
+
Sprite *Score::getSpriteById(uint16 id) {
Channel *channel = getChannelById(id);
diff --git a/engines/director/score.h b/engines/director/score.h
index f007be24638..4f92c5ed2bc 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -115,6 +115,7 @@ public:
bool checkSpriteIntersection(uint16 spriteId, Common::Point pos);
Common::List<Channel *> getSpriteIntersections(const Common::Rect &r);
uint16 getSpriteIdByMemberId(CastMemberID id);
+ bool refreshPointersForCastMemberID(CastMemberID id);
bool renderTransition(uint16 frameId, RenderMode mode);
void renderFrame(uint16 frameId, RenderMode mode = kRenderModeNormal);
Commit: 3964a56ee3d91bf959ec9bfeb7c962f13fdca565
https://github.com/scummvm/scummvm/commit/3964a56ee3d91bf959ec9bfeb7c962f13fdca565
Author: Scott Percival (code at moral.net.au)
Date: 2024-04-25T00:54:17+02:00
Commit Message:
DIRECTOR: Add 16-bit quirk for Virtual Nightclub
Changed paths:
engines/director/game-quirks.cpp
diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index e3332fc1ecd..219085ed08a 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -120,6 +120,10 @@ static void quirkLimit15FPS() {
g_director->_fpsLimit = 15;
}
+static void quirkVirtualNightclub() {
+ g_director->_colorDepth = 16;
+}
+
static void quirkHollywoodHigh() {
// Hollywood High demo has a killswitch that stops playback
// if the year is after 1996.
@@ -227,6 +231,10 @@ struct Quirk {
// Pippin game that uses Unix path separators rather than Mac
{ "pipcatalog", Common::kPlatformPippin, &quirkPipCatalog },
+ // Virtual Nightclub pops up a nag mesasage if the color depth isn't
+ // exactly 16 bit.
+ { "vnc", Common::kPlatformWindows, &quirkVirtualNightclub },
+
{ nullptr, Common::kPlatformUnknown, nullptr }
};
More information about the Scummvm-git-logs
mailing list