[Scummvm-git-logs] scummvm master -> df3c32da7b437b8074362fe3d10c88671e0e86f8
sev-
noreply at scummvm.org
Mon Jul 21 10:43:32 UTC 2025
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
47dc844da8 DIRECTOR: XOBJ: Add SmallUtil
759e9016c7 DIRECTOR: Silence noisy warning message
762f60e565 DIRECTOR: Update Flipper detection entry
1af84d2738 DIRECTOR: Make DirectorSound use int for soundChannel everywhere
8bbfda114d DIRECTOR: Mark channel dirty if the blendAmount changes
3b1b9a5e0a DIRECTOR: XOBJ: Add basic VoyagerXSound playback
3ec095a40b DIRECTOR: XOBJ: Add file read/write commands to Ednox
ef27bd06bb DIRECTOR: XOBJ: Implement more of VoyagerXSound
b0af6d4218 DIRECTOR: XOBJ: Add VMPresent stub
df3c32da7b DIRECTOR: Update detection entry for Puppet Motel
Commit: 47dc844da8fa611eb195250258b43920b0b3145a
https://github.com/scummvm/scummvm/commit/47dc844da8fa611eb195250258b43920b0b3145a
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: XOBJ: Add SmallUtil
Changed paths:
A engines/director/lingo/xlibs/smallutil.cpp
A engines/director/lingo/xlibs/smallutil.h
engines/director/lingo/lingo-object.cpp
engines/director/module.mk
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 1e43eb9fdea..20c6accfd4d 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -116,6 +116,7 @@
#include "director/lingo/xlibs/registercomponent.h"
#include "director/lingo/xlibs/remixxcmd.h"
#include "director/lingo/xlibs/serialportxobj.h"
+#include "director/lingo/xlibs/smallutil.h"
#include "director/lingo/xlibs/soundjam.h"
#include "director/lingo/xlibs/spacemgr.h"
#include "director/lingo/xlibs/stagetc.h"
@@ -316,6 +317,7 @@ static const struct XLibProto {
XLIBDEF(RolloverToolkitXtra, kXtraObj, 500), // D5
XLIBDEF(ScrnUtilXtra, kXtraObj, 500), // D5
XLIBDEF(SerialPortXObj, kXObj, 200), // D2
+ XLIBDEF(SmallUtilXObj, kXObj, 400), // D4
XLIBDEF(SoundJam, kXObj, 400), // D4
XLIBDEF(SpaceMgr, kXObj, 400), // D4
XLIBDEF(StageTCXObj, kXObj, 400), // D4
diff --git a/engines/director/lingo/xlibs/smallutil.cpp b/engines/director/lingo/xlibs/smallutil.cpp
new file mode 100644
index 00000000000..f10b0727f96
--- /dev/null
+++ b/engines/director/lingo/xlibs/smallutil.cpp
@@ -0,0 +1,112 @@
+/* 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/smallutil.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * flipper
+ *
+ **************************************************/
+
+/*
+-- SmallUtil, xobject 08Aug95 PF
+-- ©1995 - Interactive Multimedia Unit
+-- Central Queensland University
+-- CodeWarrior version, 16May95 EA
+-- xobject framework, 29nov94 JT
+--
+I mNew -- Create an instance of SmallUtil
+X mDispose -- Destroy the instance of SmallUtil
+I mQTVersion -- Return QT Version
+S mQTVersionasText -- Return QT Version as Text "."delimited
+I mSMVersion -- Return Sound Manager Version
+S mSMVersionasText -- Return Sound Manager Version "." delimited
+S mFontList -- Return List of FOND's
+S mVolumeList -- Return List of Mounted Volumes
+ */
+
+namespace Director {
+
+const char *SmallUtilXObj::xlibName = "SmallUtil";
+const XlibFileDesc SmallUtilXObj::fileNames[] = {
+ { "SmallUtil", nullptr },
+ { nullptr, nullptr },
+};
+
+static MethodProto xlibMethods[] = {
+ { "new", SmallUtilXObj::m_new, 0, 0, 400 },
+ { "dispose", SmallUtilXObj::m_dispose, 0, 0, 400 },
+ { "qTVersion", SmallUtilXObj::m_qTVersion, 0, 0, 400 },
+ { "qTVersionasText", SmallUtilXObj::m_qTVersionasText, 0, 0, 400 },
+ { "sMVersion", SmallUtilXObj::m_sMVersion, 0, 0, 400 },
+ { "sMVersionasText", SmallUtilXObj::m_sMVersionasText, 0, 0, 400 },
+ { "fontList", SmallUtilXObj::m_fontList, 0, 0, 400 },
+ { "volumeList", SmallUtilXObj::m_volumeList, 0, 0, 400 },
+ { nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+SmallUtilXObject::SmallUtilXObject(ObjectType ObjectType) :Object<SmallUtilXObject>("SmallUtil") {
+ _objType = ObjectType;
+}
+
+void SmallUtilXObj::open(ObjectType type, const Common::Path &path) {
+ SmallUtilXObject::initMethods(xlibMethods);
+ SmallUtilXObject *xobj = new SmallUtilXObject(type);
+ if (type == kXtraObj)
+ g_lingo->_openXtras.push_back(xlibName);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void SmallUtilXObj::close(ObjectType type) {
+ SmallUtilXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void SmallUtilXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("SmallUtilXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
+ g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUBNR(SmallUtilXObj::m_dispose)
+XOBJSTUB(SmallUtilXObj::m_qTVersion, 0)
+XOBJSTUB(SmallUtilXObj::m_qTVersionasText, "2.5")
+XOBJSTUB(SmallUtilXObj::m_sMVersion, 0)
+XOBJSTUB(SmallUtilXObj::m_sMVersionasText, "3.2")
+XOBJSTUB(SmallUtilXObj::m_fontList, "")
+XOBJSTUB(SmallUtilXObj::m_volumeList, "")
+
+}
diff --git a/engines/director/lingo/xlibs/smallutil.h b/engines/director/lingo/xlibs/smallutil.h
new file mode 100644
index 00000000000..55ff9ef1001
--- /dev/null
+++ b/engines/director/lingo/xlibs/smallutil.h
@@ -0,0 +1,53 @@
+/* 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_SMALLUTIL_H
+#define DIRECTOR_LINGO_XLIBS_SMALLUTIL_H
+
+namespace Director {
+
+class SmallUtilXObject : public Object<SmallUtilXObject> {
+public:
+ SmallUtilXObject(ObjectType objType);
+};
+
+namespace SmallUtilXObj {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_qTVersion(int nargs);
+void m_qTVersionasText(int nargs);
+void m_sMVersion(int nargs);
+void m_sMVersionasText(int nargs);
+void m_fontList(int nargs);
+void m_volumeList(int nargs);
+
+} // End of namespace SmallUtilXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 34e7b767ad6..87e969250b7 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -146,6 +146,7 @@ MODULE_OBJS = \
lingo/xlibs/registercomponent.o \
lingo/xlibs/remixxcmd.o \
lingo/xlibs/serialportxobj.o \
+ lingo/xlibs/smallutil.o \
lingo/xlibs/soundjam.o \
lingo/xlibs/spacemgr.o \
lingo/xlibs/stagetc.o \
Commit: 759e9016c7284dfce04663e09d3ac469dd91d09e
https://github.com/scummvm/scummvm/commit/759e9016c7284dfce04663e09d3ac469dd91d09e
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: Silence noisy warning message
Changed paths:
engines/director/cursor.cpp
diff --git a/engines/director/cursor.cpp b/engines/director/cursor.cpp
index b0fb0e6ec1e..666beeb7e98 100644
--- a/engines/director/cursor.cpp
+++ b/engines/director/cursor.cpp
@@ -159,7 +159,7 @@ void Cursor::readFromCast(Datum cursorCasts) {
}
void Cursor::readBuiltinType(Datum resourceId) {
- if (resourceId.equalTo(_cursorResId))
+ if (resourceId.type == _cursorResId.type && resourceId.equalTo(_cursorResId))
return;
if (resourceId.type != INT) {
@@ -194,7 +194,7 @@ void Cursor::readBuiltinType(Datum resourceId) {
}
void Cursor::readFromResource(Datum resourceId) {
- if (resourceId == _cursorResId)
+ if (resourceId.type == _cursorResId.type && resourceId.equalTo(_cursorResId))
return;
if (resourceId.type != INT) {
Commit: 762f60e565ac8ead39dd6c16756e5840a2291a0a
https://github.com/scummvm/scummvm/commit/762f60e565ac8ead39dd6c16756e5840a2291a0a
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: Update Flipper detection entry
Changed paths:
engines/director/detection_tables.h
engines/director/game-quirks.cpp
diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index 988fe93ccc0..e3a0be8c65b 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -6918,9 +6918,9 @@ static const DirectorGameDescription gameDescriptions[] = {
// Developed by Brilliant Interactive Ideas, published by Brainstorm
// Win version needs extraction/installation (DATA.Z)
- MACGAME1("flipper", "", "Flipper/Flipper!", "rt:7130f0fd98e0b169a2f3bfeb6fbded9a", 718125, 501),
- WINGAME2("flipper", "", "FLIP32.EXE", "t:f5f0b26a2506fadac19f66cc2ae235f9", 1398201,
- "FLIPPER/CPA24.DXR", "d:fcfd7c09d92797fa42f4a38a301b8c13", 2780110, 500),
+ MACGAME1f("flipper", "", "Flipper/Flipper!", "rt:7130f0fd98e0b169a2f3bfeb6fbded9a", 718125, 501, GF_32BPP),
+ WINGAME2f("flipper", "", "FLIP32.EXE", "t:f5f0b26a2506fadac19f66cc2ae235f9", 1398201,
+ "FLIPPER/CPA24.DXR", "d:fcfd7c09d92797fa42f4a38a301b8c13", 2780110, 500, GF_32BPP),
MACGAME1("fplit", "", "Toyland", "r:7fc35c7129cb027987528b027c6cc27c", 705445, 500),
WINGAME2("fplit", "", "PIR32BIT/START32.EXE", "t:564db7e9ffacb6c0fecbf83c1f988069", 1394437,
diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index 234d5365765..0a1cee574af 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -256,6 +256,8 @@ const struct Quirk {
{ "vnc", Common::kPlatformMacintosh, &quirkPretend16Bit },
{ "finkletimes", Common::kPlatformWindows, &quirkPretend16Bit },
{ "finkletimes", Common::kPlatformMacintosh, &quirkPretend16Bit },
+ { "flipper", Common::kPlatformMacintosh, &quirkPretend16Bit },
+ { "flipper", Common::kPlatformWindows, &quirkPretend16Bit },
{ nullptr, Common::kPlatformUnknown, nullptr }
};
Commit: 1af84d273895900d1f61cb49b2b580189864873a
https://github.com/scummvm/scummvm/commit/1af84d273895900d1f61cb49b2b580189864873a
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: Make DirectorSound use int for soundChannel everywhere
Changed paths:
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 65f01a82a41..c7e2f4f0e84 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -68,13 +68,13 @@ DirectorSound::~DirectorSound() {
delete it._value;
}
-SoundChannel *DirectorSound::getChannel(uint8 soundChannel) {
+SoundChannel *DirectorSound::getChannel(int soundChannel) {
if (!assertChannel(soundChannel))
return nullptr;
return _channels[soundChannel];
}
-void DirectorSound::playFile(Common::String filename, uint8 soundChannel) {
+void DirectorSound::playFile(Common::String filename, int soundChannel) {
if (!assertChannel(soundChannel))
return;
@@ -103,7 +103,7 @@ void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to)
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_scriptSound, subSeekStream);
}
-uint8 DirectorSound::getChannelVolume(uint8 soundChannel) {
+uint8 DirectorSound::getChannelVolume(int soundChannel) {
if (!assertChannel(soundChannel))
return 0;
@@ -116,7 +116,7 @@ void DirectorSound::setChannelDefaultVolume(int soundChannel) {
_channels[soundChannel]->volume = vol;
}
-void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
+void DirectorSound::playStream(Audio::AudioStream &stream, int soundChannel) {
if (!assertChannel(soundChannel))
return;
@@ -129,7 +129,7 @@ void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel]->handle, &stream, -1, getChannelVolume(soundChannel));
}
-void DirectorSound::playSound(SoundID soundID, uint8 soundChannel, bool forPuppet) {
+void DirectorSound::playSound(SoundID soundID, int soundChannel, bool forPuppet) {
switch (soundID.type) {
case kSoundCast:
playCastMember(CastMemberID(soundID.u.cast.member, soundID.u.cast.castLib), soundChannel, forPuppet);
@@ -140,7 +140,7 @@ void DirectorSound::playSound(SoundID soundID, uint8 soundChannel, bool forPuppe
}
}
-void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bool forPuppet) {
+void DirectorSound::playCastMember(CastMemberID memberID, int soundChannel, bool forPuppet) {
if (!assertChannel(soundChannel))
return;
@@ -257,7 +257,7 @@ void SNDDecoder::loadExternalSoundStream(Common::SeekableReadStreamEndian &strea
_channels = 1;
}
-void DirectorSound::registerFade(uint8 soundChannel, bool fadeIn, int ticks) {
+void DirectorSound::registerFade(int soundChannel, bool fadeIn, int ticks) {
if (!assertChannel(soundChannel))
return;
@@ -307,7 +307,7 @@ bool DirectorSound::fadeChannels() {
return ongoing;
}
-void DirectorSound::cancelFade(uint8 soundChannel) {
+void DirectorSound::cancelFade(int soundChannel) {
if (!assertChannel(soundChannel))
return;
// NOTE: It is assumed that soundChannel has already been validated, which is
@@ -323,7 +323,7 @@ void DirectorSound::cancelFade(uint8 soundChannel) {
}
}
-bool DirectorSound::isChannelActive(uint8 soundChannel) {
+bool DirectorSound::isChannelActive(int soundChannel) {
if (!assertChannel(soundChannel))
return false;
@@ -427,7 +427,7 @@ void DirectorSound::unloadSampleSounds() {
}
}
-void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel) {
+void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, int soundChannel) {
if (!assertChannel(soundChannel))
return;
@@ -479,21 +479,21 @@ void DirectorSound::changingMovie() {
unloadSampleSounds(); // TODO: we can possibly keep this between movies
}
-void DirectorSound::setLastPlayedSound(uint8 soundChannel, SoundID soundId, bool stopOnZero) {
+void DirectorSound::setLastPlayedSound(int soundChannel, SoundID soundId, bool stopOnZero) {
_channels[soundChannel]->lastPlayedSound = soundId;
_channels[soundChannel]->stopOnZero = stopOnZero;
_channels[soundChannel]->movieChanged = false;
}
-bool DirectorSound::isLastPlayedSound(uint8 soundChannel, const SoundID &soundId) {
+bool DirectorSound::isLastPlayedSound(int soundChannel, const SoundID &soundId) {
return !_channels[soundChannel]->movieChanged && _channels[soundChannel]->lastPlayedSound == soundId;
}
-bool DirectorSound::shouldStopOnZero(uint8 soundChannel) {
+bool DirectorSound::shouldStopOnZero(int soundChannel) {
return _channels[soundChannel]->stopOnZero;
}
-void DirectorSound::stopSound(uint8 soundChannel) {
+void DirectorSound::stopSound(int soundChannel) {
if (!assertChannel(soundChannel))
return;
@@ -529,7 +529,7 @@ void DirectorSound::systemBeep() {
_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
}
-bool DirectorSound::isChannelPuppet(uint8 soundChannel) {
+bool DirectorSound::isChannelPuppet(int soundChannel) {
if (!assertChannel(soundChannel))
return false;
@@ -540,7 +540,7 @@ bool DirectorSound::isChannelPuppet(uint8 soundChannel) {
return true;
}
-void DirectorSound::setPuppetSound(SoundID soundId, uint8 soundChannel) {
+void DirectorSound::setPuppetSound(SoundID soundId, int soundChannel) {
if (!assertChannel(soundChannel))
return;
@@ -549,7 +549,7 @@ void DirectorSound::setPuppetSound(SoundID soundId, uint8 soundChannel) {
_channels[soundChannel]->stopOnZero = true;
}
-void DirectorSound::playPuppetSound(uint8 soundChannel) {
+void DirectorSound::playPuppetSound(int soundChannel) {
if (!assertChannel(soundChannel))
return;
@@ -643,7 +643,7 @@ void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayLis
playFPlaySound();
}
-void DirectorSound::setChannelVolumeInternal(uint8 soundChannel, uint8 volume) {
+void DirectorSound::setChannelVolumeInternal(int soundChannel, uint8 volume) {
if (!(_channels[soundChannel]) || volume == _channels[soundChannel]->volume)
return;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index b1d4aae19cd..8c53c8fcca0 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -176,13 +176,13 @@ public:
DirectorSound(Window *window);
~DirectorSound();
- SoundChannel *getChannel(uint8 soundChannel);
- void playFile(Common::String filename, uint8 soundChannel);
+ SoundChannel *getChannel(int soundChannel);
+ void playFile(Common::String filename, int soundChannel);
void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
- void playStream(Audio::AudioStream &stream, uint8 soundChannel);
- void playSound(SoundID soundId, uint8 soundChannel, bool forPuppet = false);
- void playCastMember(CastMemberID memberID, uint8 soundChannel, bool forPuppet = false);
- void playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel);
+ void playStream(Audio::AudioStream &stream, int soundChannel);
+ void playSound(SoundID soundId, int soundChannel, bool forPuppet = false);
+ void playCastMember(CastMemberID memberID, int soundChannel, bool forPuppet = false);
+ void playExternalSound(uint16 menu, uint16 submenu, int soundChannel);
void playFPlaySound(const Common::Array<Common::String> &fplayList);
void playFPlaySound();
void setSoundEnabled(bool enabled);
@@ -192,32 +192,32 @@ public:
void loadSampleSounds(uint type);
void unloadSampleSounds();
- bool isChannelPuppet(uint8 soundChannel);
- void setPuppetSound(SoundID soundId, uint8 soundChannel);
- void playPuppetSound(uint8 soundChannel);
+ bool isChannelPuppet(int soundChannel);
+ void setPuppetSound(SoundID soundId, int soundChannel);
+ void playPuppetSound(int soundChannel);
bool getSoundEnabled() { return _enable; }
Common::String getCurrentSound() { return _currentSoundName; }
- void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
+ void registerFade(int soundChannel, bool fadeIn, int ticks);
bool fadeChannels();
- bool isChannelActive(uint8 soundChannel);
- uint8 getChannelVolume(uint8 soundChannel);
+ bool isChannelActive(int soundChannel);
+ uint8 getChannelVolume(int soundChannel);
void setChannelVolume(int channel, uint8 volume);
- void stopSound(uint8 soundChannel);
+ void stopSound(int soundChannel);
void stopSound();
void setChannelDefaultVolume(int soundChannel);
private:
- void setLastPlayedSound(uint8 soundChannel, SoundID soundId, bool stopOnZero = true);
- bool isLastPlayedSound(uint8 soundChannel, const SoundID &soundId);
- bool shouldStopOnZero(uint8 soundChannel);
+ void setLastPlayedSound(int soundChannel, SoundID soundId, bool stopOnZero = true);
+ bool isLastPlayedSound(int soundChannel, const SoundID &soundId);
+ bool shouldStopOnZero(int soundChannel);
- void setChannelVolumeInternal(uint8 soundChannel, uint8 volume);
+ void setChannelVolumeInternal(int soundChannel, uint8 volume);
bool assertChannel(int soundChannel);
- void cancelFade(uint8 soundChannel);
+ void cancelFade(int soundChannel);
};
class AudioDecoder {
Commit: 8bbfda114ddc40dfe9f3a4d897f92a3537064d47
https://github.com/scummvm/scummvm/commit/8bbfda114ddc40dfe9f3a4d897f92a3537064d47
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: Mark channel dirty if the blendAmount changes
Fixes fade of sprites in the introduction of Puppet Motel.
Changed paths:
engines/director/channel.cpp
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index db14e8d2631..540d1930346 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -255,7 +255,8 @@ bool Channel::isDirty(Sprite *nextSprite) {
// modified.
isDirtyFlag |= _sprite->_castId != nextSprite->_castId ||
_sprite->_ink != nextSprite->_ink || _sprite->_backColor != nextSprite->_backColor ||
- _sprite->_foreColor != nextSprite->_foreColor;
+ _sprite->_foreColor != nextSprite->_foreColor || _sprite->_blend != nextSprite->_blend ||
+ _sprite->_blendAmount != nextSprite->_blendAmount || _sprite->_thickness != nextSprite->_thickness;
if (!_sprite->_moveable)
isDirtyFlag |= _sprite->getPosition() != nextSprite->getPosition();
if (isStretched() && !hasTextCastMember(_sprite))
Commit: 3b1b9a5e0a401b11665da666da2712e2044973e9
https://github.com/scummvm/scummvm/commit/3b1b9a5e0a401b11665da666da2712e2044973e9
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: XOBJ: Add basic VoyagerXSound playback
Fixes scripting and sound playback of Puppet Motel.
Changed paths:
engines/director/lingo/xlibs/voyagerxsound.cpp
engines/director/lingo/xlibs/voyagerxsound.h
diff --git a/engines/director/lingo/xlibs/voyagerxsound.cpp b/engines/director/lingo/xlibs/voyagerxsound.cpp
index 51e524ddbec..c888a923c9e 100644
--- a/engines/director/lingo/xlibs/voyagerxsound.cpp
+++ b/engines/director/lingo/xlibs/voyagerxsound.cpp
@@ -22,6 +22,7 @@
#include "common/system.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"
@@ -109,6 +110,41 @@ static BuiltinProto xlibBuiltins[] = {
VoyagerXSoundXObject::VoyagerXSoundXObject(ObjectType ObjectType) :Object<VoyagerXSoundXObject>("XSound") {
_objType = ObjectType;
+ _soundManager = g_director->getCurrentWindow()->getSoundManager();
+
+}
+
+VoyagerXSoundXObject::~VoyagerXSoundXObject() {
+ close();
+}
+
+int VoyagerXSoundXObject::open(int numChan, int monoStereo) {
+ if (!_channels.contains(numChan)) {
+ _channels[numChan] = new VoyagerChannel();
+ _channels[numChan]->channelID = numChan + 1000;
+ }
+ return 1;
+}
+
+void VoyagerXSoundXObject::close() {
+ for (auto &it : _channels)
+ delete it._value;
+ _channels.clear();
+}
+
+int VoyagerXSoundXObject::status(int chan) {
+ if (_channels.contains(chan)) {
+ return _soundManager->isChannelActive(_channels[chan]->channelID) ? 1 : 0;
+ }
+ return 0;
+}
+
+int VoyagerXSoundXObject::playfile(int chan, Common::String &path, int tstart, int tend) {
+ if (!_channels.contains(chan)) {
+ open(chan, 2);
+ }
+ _soundManager->playFile(path, _channels[chan]->channelID);
+ return 1;
}
void VoyagerXSoundXObj::open(ObjectType type, const Common::Path &path) {
@@ -123,7 +159,6 @@ void VoyagerXSoundXObj::open(ObjectType type, const Common::Path &path) {
void VoyagerXSoundXObj::close(ObjectType type) {
VoyagerXSoundXObject::cleanupMethods();
g_lingo->_globalvars[xlibName] = Datum();
-
}
void VoyagerXSoundXObj::m_new(int nargs) {
@@ -132,18 +167,72 @@ void VoyagerXSoundXObj::m_new(int nargs) {
g_lingo->push(g_lingo->_state->me);
}
+
// For some reason the game code calls all of these with ARGC, so always return something
XOBJSTUBNR(VoyagerXSoundXObj::m_dispose)
XOBJSTUBNR(VoyagerXSoundXObj::m_init)
-XOBJSTUB(VoyagerXSoundXObj::m_open, 0)
-XOBJSTUB(VoyagerXSoundXObj::m_close, 0)
+
+void VoyagerXSoundXObj::m_open(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_open", nargs);
+ ARGNUMCHECK(2);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ Datum monoStereo = g_lingo->pop();
+ Datum numChan = g_lingo->pop();
+ int result = me->open(numChan.asInt(), monoStereo.asInt());
+ g_lingo->push(result);
+}
+
+void VoyagerXSoundXObj::m_close(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_close", nargs);
+ ARGNUMCHECK(0);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ me->close();
+ g_lingo->push(0);
+}
+
XOBJSTUB(VoyagerXSoundXObj::m_bufsize, 0)
XOBJSTUB(VoyagerXSoundXObj::m_exists, 0)
-XOBJSTUB(VoyagerXSoundXObj::m_status, 0)
+
+void VoyagerXSoundXObj::m_status(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_status", nargs);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ ARGNUMCHECK(1);
+ Datum chan = g_lingo->pop();
+ g_lingo->push(me->status(chan.asInt()));
+}
+
XOBJSTUB(VoyagerXSoundXObj::m_path, 0)
XOBJSTUB(VoyagerXSoundXObj::m_duration, "")
XOBJSTUB(VoyagerXSoundXObj::m_curtime, "")
-XOBJSTUB(VoyagerXSoundXObj::m_playfile, 0)
+
+void VoyagerXSoundXObj::m_playfile(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_playfile", nargs);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ if (nargs < 2) {
+ warning("VoyagerXSoundXObj::m_playfile: expected at least 2 args");
+ g_lingo->dropStack(nargs);
+ g_lingo->push(0);
+ return;
+ } else if (nargs > 4) {
+ g_lingo->dropStack(nargs - 4);
+ nargs = 4;
+ }
+ Datum tend(-1);
+ if (nargs == 4) {
+ tend = g_lingo->pop();
+ nargs--;
+ }
+ Datum tstart(-1);
+ if (nargs == 3) {
+ tstart = g_lingo->pop();
+ nargs--;
+ }
+ Common::String path = g_lingo->pop().asString();
+ Datum chan = g_lingo->pop();
+ int result = me->playfile(chan.asInt(), path, tstart.asInt(), tend.asInt());
+ g_lingo->push(result);
+}
+
XOBJSTUB(VoyagerXSoundXObj::m_loadfile, 0)
XOBJSTUB(VoyagerXSoundXObj::m_unloadfile, 0)
XOBJSTUB(VoyagerXSoundXObj::m_playsnd, 0)
diff --git a/engines/director/lingo/xlibs/voyagerxsound.h b/engines/director/lingo/xlibs/voyagerxsound.h
index da9d7620224..472ec4f21da 100644
--- a/engines/director/lingo/xlibs/voyagerxsound.h
+++ b/engines/director/lingo/xlibs/voyagerxsound.h
@@ -22,11 +22,27 @@
#ifndef DIRECTOR_LINGO_XLIBS_VOYAGERXSOUND_H
#define DIRECTOR_LINGO_XLIBS_VOYAGERXSOUND_H
+#include "director/sound.h"
+
namespace Director {
+struct VoyagerChannel {
+ int channelID;
+};
+
class VoyagerXSoundXObject : public Object<VoyagerXSoundXObject> {
public:
VoyagerXSoundXObject(ObjectType objType);
+ ~VoyagerXSoundXObject();
+
+ int open(int monoStereo, int numChan);
+ void close();
+ int status(int chan);
+ int playfile(int chan, Common::String &path, int tstart, int tend);
+
+ DirectorSound *_soundManager;
+
+ Common::HashMap<int, VoyagerChannel *> _channels;
};
namespace VoyagerXSoundXObj {
Commit: 3ec095a40b0260dd229f737b212fd0c73935a7c3
https://github.com/scummvm/scummvm/commit/3ec095a40b0260dd229f737b212fd0c73935a7c3
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: XOBJ: Add file read/write commands to Ednox
Fixes save games in Grackon's Curse.
Changed paths:
engines/director/lingo/xlibs/ednox.cpp
diff --git a/engines/director/lingo/xlibs/ednox.cpp b/engines/director/lingo/xlibs/ednox.cpp
index 8171ec8560b..d97a0d6c382 100644
--- a/engines/director/lingo/xlibs/ednox.cpp
+++ b/engines/director/lingo/xlibs/ednox.cpp
@@ -55,6 +55,7 @@
* SSS deleteDocumentFile,hDir,hFile -- delete a file from the directory
*/
+#include "common/savefile.h"
#include "director/director.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-object.h"
@@ -121,13 +122,6 @@ void Ednox::m_new(int nargs) {
XOBJSTUBNR(Ednox::m_dispose)
-void Ednox::m_getdocumentfile(int nargs) {
- // Common::U32String hFile = g_lingo->pop().asString();
- // Common::U32String hDir = g_lingo->pop().asString();
- g_lingo->printSTUBWithArglist("Ednox::m_getdocumentfile", nargs);
- g_lingo->dropStack(nargs);
-}
-
void Ednox::m_getpathx(int nargs) {
/* int mMacMode = */ g_lingo->pop().asInt();
Common::U32String hStrIn = g_lingo->pop().asString();
@@ -145,25 +139,17 @@ void Ednox::m_iscdx(int nargs) {
Common::U32String hDrive = g_lingo->pop().asString();
// g_lingo->printSTUBWithArglist("Ednox::m_iscdx", nargs);
if (hDrive == "d:\\"){
- g_lingo->push(Datum(0));
+ g_lingo->push(Datum("0"));
} else {
- g_lingo->push(Datum(-1));
+ g_lingo->push(Datum("-1"));
}
}
-void Ednox::m_savedocumentfile(int nargs) {
- // Common::U32String hStrIn = g_lingo->pop().asString();
- // Common::U32String hFile = g_lingo->pop().asString();
- // Common::U32String hDir = g_lingo->pop().asString();
- g_lingo->printSTUBWithArglist("Ednox::m_savedocumentfile", nargs);
- g_lingo->dropStack(nargs);
-}
-
void Ednox::m_setdrivex(int nargs) {
// Common::U32String hStrIn = g_lingo->pop().asString();
g_lingo->printSTUBWithArglist("Ednox::m_setdrivex", nargs);
g_lingo->dropStack(nargs);
- g_lingo->push(Datum(0));
+ g_lingo->push(Datum("1"));
}
XOBJSTUB(Ednox::m_checksoundx, "")
@@ -185,12 +171,71 @@ void Ednox::m_drawbkgndx(int nargs) {
}
void Ednox::m_getdocumentname(int nargs) {
- // Common::U32String hExt = g_lingo->pop().asString();
- // Common::U32String hDir = g_lingo->pop().asString();
+ Common::SaveFileManager *saves = g_system->getSavefileManager();
+ Common::String prefix = savePrefix();
g_lingo->printSTUBWithArglist("Ednox::m_getdocumentname", nargs);
- g_lingo->dropStack(nargs);
+ ARGNUMCHECK(2);
+ Common::String hExt = g_lingo->pop().asString();
+ Common::String hDir = g_lingo->pop().asString();
+ Common::String result;
+ Common::StringArray existing = saves->listSavefiles(Common::String::format("%s*", prefix.c_str()));
+ bool first = true;
+ for (auto &it : existing) {
+ if (first)
+ first = false;
+ else
+ result += ",";
+ result += it.substr(prefix.size());
+ }
+ g_lingo->push(result);
}
+void Ednox::m_getdocumentfile(int nargs) {
+ Common::SaveFileManager *saves = g_system->getSavefileManager();
+ Common::String prefix = savePrefix();
+ g_lingo->printSTUBWithArglist("Ednox::m_getdocumentfile", nargs);
+ ARGNUMCHECK(2);
+ Common::String hFile = g_lingo->pop().asString();
+ Common::String hDir = g_lingo->pop().asString();
+
+ Common::String filename = prefix + hFile;
+ // ignore the directory, we just care about the filename
+ if (!saves->exists(filename)) {
+ warning("Ednox::m_getdocumentfile: No file exists for %s", filename.c_str());
+ g_lingo->push(Datum());
+ return;
+ }
+ Common::SeekableReadStream *stream = saves->openForLoading(filename);
+ if (!stream) {
+ warning("Ednox::m_getdocumentfile: Unable to open file %s", filename.c_str());
+ g_lingo->push(Datum());
+ return;
+ }
+ Common::String result = stream->readString();
+ delete stream;
+ g_lingo->push(Datum(result));
+}
+
+void Ednox::m_savedocumentfile(int nargs) {
+ Common::SaveFileManager *saves = g_system->getSavefileManager();
+ g_lingo->printSTUBWithArglist("Ednox::m_savedocumentfile", nargs);
+ ARGNUMCHECK(3);
+ Common::String hStrIn = g_lingo->pop().asString();
+ Common::String hFile = g_lingo->pop().asString();
+ Common::String hDir = g_lingo->pop().asString();
+ Common::String filename = savePrefix() + hFile;
+ Common::SeekableWriteStream *stream = saves->openForSaving(filename, false);
+ if (!stream) {
+ warning("Ednox::m_savedocumentfile: Unable to open file %s", filename.c_str());
+ g_lingo->push(Datum());
+ return;
+ }
+ stream->writeString(hStrIn);
+ delete stream;
+ g_lingo->push(Common::String(""));
+}
+
+
void Ednox::m_error(int nargs) {
// int code = g_lingo->pop().asInt();
g_lingo->printSTUBWithArglist("Ednox::m_error", nargs);
Commit: ef27bd06bb18b1b8fcf364f24d3eba04f0d954e9
https://github.com/scummvm/scummvm/commit/ef27bd06bb18b1b8fcf364f24d3eba04f0d954e9
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: XOBJ: Implement more of VoyagerXSound
Fixes more transitions and features in Puppet Motel.
Changed paths:
engines/director/lingo/xlibs/voyagerxsound.cpp
engines/director/lingo/xlibs/voyagerxsound.h
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/lingo/xlibs/voyagerxsound.cpp b/engines/director/lingo/xlibs/voyagerxsound.cpp
index c888a923c9e..0df3c6ea877 100644
--- a/engines/director/lingo/xlibs/voyagerxsound.cpp
+++ b/engines/director/lingo/xlibs/voyagerxsound.cpp
@@ -22,6 +22,8 @@
#include "common/system.h"
#include "director/director.h"
+#include "director/movie.h"
+#include "director/score.h"
#include "director/window.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-object.h"
@@ -147,6 +149,42 @@ int VoyagerXSoundXObject::playfile(int chan, Common::String &path, int tstart, i
return 1;
}
+int VoyagerXSoundXObject::fade(int chan, int endvol, int duration, bool autostop) {
+ if (!_channels.contains(chan)) {
+ return 0;
+ }
+ int channelID = _channels[chan]->channelID;
+ _soundManager->registerFade(channelID, _soundManager->getChannelVolume(channelID), endvol, duration*60, autostop);
+ Window *window = g_director->getCurrentWindow();
+ Score *score = window->getCurrentMovie()->getScore();
+ score->_activeFade = true;
+ return 1;
+}
+
+void VoyagerXSoundXObject::stop(int chan) {
+ if (!_channels.contains(chan)) {
+ return;
+ }
+ int channelID = _channels[chan]->channelID;
+ _soundManager->stopSound(channelID);
+}
+
+void VoyagerXSoundXObject::volume(int chan, int vol) {
+ if (!_channels.contains(chan)) {
+ return;
+ }
+ int channelID = _channels[chan]->channelID;
+ _soundManager->setChannelVolume(channelID, vol);
+}
+
+void VoyagerXSoundXObject::frequency(int chan, int percent) {
+ if (!_channels.contains(chan)) {
+ return;
+ }
+ int channelID = _channels[chan]->channelID;
+ _soundManager->setChannelPitchShift(channelID, percent);
+}
+
void VoyagerXSoundXObj::open(ObjectType type, const Common::Path &path) {
VoyagerXSoundXObject::initMethods(xlibMethods);
VoyagerXSoundXObject *xobj = new VoyagerXSoundXObject(type);
@@ -235,13 +273,75 @@ void VoyagerXSoundXObj::m_playfile(int nargs) {
XOBJSTUB(VoyagerXSoundXObj::m_loadfile, 0)
XOBJSTUB(VoyagerXSoundXObj::m_unloadfile, 0)
-XOBJSTUB(VoyagerXSoundXObj::m_playsnd, 0)
+
+void VoyagerXSoundXObj::m_playsnd(int nargs) {
+ m_playfile(nargs);
+}
+
XOBJSTUB(VoyagerXSoundXObj::m_extplayfile, 0)
-XOBJSTUB(VoyagerXSoundXObj::m_stop, 0)
-XOBJSTUB(VoyagerXSoundXObj::m_volume, 0)
+
+void VoyagerXSoundXObj::m_stop(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_stop", nargs);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ ARGNUMCHECK(1);
+ int chan = g_lingo->pop().asInt();
+ me->stop(chan);
+ g_lingo->push(Datum(1));
+}
+
+void VoyagerXSoundXObj::m_volume(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_volume", nargs);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ ARGNUMCHECK(2);
+ int vol = g_lingo->pop().asInt();
+ int chan = g_lingo->pop().asInt();
+ me->volume(chan, vol);
+ g_lingo->push(Datum(1));
+}
+
XOBJSTUB(VoyagerXSoundXObj::m_leftrightvol, 0)
-XOBJSTUB(VoyagerXSoundXObj::m_fade, 0)
-XOBJSTUB(VoyagerXSoundXObj::m_frequency, 0)
+
+void VoyagerXSoundXObj::m_fade(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_fade", nargs);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ if (nargs < 2) {
+ warning("VoyagerXSoundXObj::m_fade: expected at least 2 args");
+ g_lingo->dropStack(nargs);
+ g_lingo->push(Datum());
+ return;
+ }
+ if (nargs > 4) {
+ warning("VoyagerXSoundXObj: dropping %d extra args", nargs - 4);
+ g_lingo->dropStack(nargs - 4);
+ nargs = 4;
+ }
+ bool autoStop = false;
+ int duration = 0;
+ if (nargs == 4) {
+ autoStop = (bool)g_lingo->pop().asInt();
+ nargs--;
+ }
+ if (nargs == 3) {
+ duration = g_lingo->pop().asInt();
+ nargs--;
+ }
+ int endVol = g_lingo->pop().asInt();
+ int chan = g_lingo->pop().asInt();
+
+ g_lingo->push(Datum(me->fade(chan, endVol, duration, autoStop)));
+}
+
+void VoyagerXSoundXObj::m_frequency(int nargs) {
+ g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_frequency", nargs);
+ VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+ ARGNUMCHECK(2);
+ int percent = g_lingo->pop().asInt();
+ int chan = g_lingo->pop().asInt();
+ me->frequency(chan, percent);
+ g_lingo->push(Datum(1));
+}
+
+
XOBJSTUB(VoyagerXSoundXObj::m_pan, 0)
XOBJSTUB(VoyagerXSoundXObj::m_startrecord, 0)
XOBJSTUB(VoyagerXSoundXObj::m_stoprecord, 0)
diff --git a/engines/director/lingo/xlibs/voyagerxsound.h b/engines/director/lingo/xlibs/voyagerxsound.h
index 472ec4f21da..b40e9f227d4 100644
--- a/engines/director/lingo/xlibs/voyagerxsound.h
+++ b/engines/director/lingo/xlibs/voyagerxsound.h
@@ -39,6 +39,10 @@ public:
void close();
int status(int chan);
int playfile(int chan, Common::String &path, int tstart, int tend);
+ int fade(int chan, int endvol, int duration, bool autostop);
+ void stop(int chan);
+ void volume(int chan, int vol);
+ void frequency(int chan, int percent);
DirectorSound *_soundManager;
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index c7e2f4f0e84..75ed5d57e95 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -89,6 +89,10 @@ void DirectorSound::playFile(Common::String filename, int soundChannel) {
setChannelDefaultVolume(soundChannel);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel]->handle, sound, -1, getChannelVolume(soundChannel));
+ _channels[soundChannel]->originalRate = (int)_mixer->getChannelRate(_channels[soundChannel]->handle);
+ if (_channels[soundChannel]->pitchShiftPercent != 100) {
+ _mixer->setChannelRate(_channels[soundChannel]->handle, _channels[soundChannel]->originalRate*_channels[soundChannel]->pitchShiftPercent/100);
+ }
// Set the last played sound so that cast member 0 in the sound channel doesn't stop this file.
setLastPlayedSound(soundChannel, SoundID(), false);
@@ -116,6 +120,14 @@ void DirectorSound::setChannelDefaultVolume(int soundChannel) {
_channels[soundChannel]->volume = vol;
}
+void DirectorSound::setChannelPitchShift(int soundChannel, int pitchShiftPercent) {
+ _channels[soundChannel]->pitchShiftPercent = pitchShiftPercent;
+ if (isChannelActive(soundChannel)) {
+ _mixer->setChannelRate(_channels[soundChannel]->handle, _channels[soundChannel]->originalRate*_channels[soundChannel]->pitchShiftPercent/100);
+ }
+}
+
+
void DirectorSound::playStream(Audio::AudioStream &stream, int soundChannel) {
if (!assertChannel(soundChannel))
return;
@@ -126,7 +138,12 @@ void DirectorSound::playStream(Audio::AudioStream &stream, int soundChannel) {
setChannelDefaultVolume(soundChannel);
+
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel]->handle, &stream, -1, getChannelVolume(soundChannel));
+ _channels[soundChannel]->originalRate = (int)_mixer->getChannelRate(_channels[soundChannel]->handle);
+ if (_channels[soundChannel]->pitchShiftPercent != 100) {
+ _mixer->setChannelRate(_channels[soundChannel]->handle, _channels[soundChannel]->originalRate*_channels[soundChannel]->pitchShiftPercent/100);
+ }
}
void DirectorSound::playSound(SoundID soundID, int soundChannel, bool forPuppet) {
@@ -257,11 +274,20 @@ void SNDDecoder::loadExternalSoundStream(Common::SeekableReadStreamEndian &strea
_channels = 1;
}
-void DirectorSound::registerFade(int soundChannel, bool fadeIn, int ticks) {
+void DirectorSound::registerFade(int soundChannel, bool fadeIn, int ticks, bool autoStop) {
if (!assertChannel(soundChannel))
return;
- debugC(5, kDebugSound, "DirectorSound::registerFade(): registered fading channel %d %s over %d ticks", soundChannel, fadeIn ? "in" : "out", ticks);
+ int startVol = fadeIn ? 0 : _channels[soundChannel]->volume;
+ int targetVol = fadeIn ? _channels[soundChannel]->volume : 0;
+ registerFade(soundChannel, startVol, targetVol, ticks, autoStop);
+}
+
+void DirectorSound::registerFade(int soundChannel, int startVol, int targetVol, int ticks, bool autoStop) {
+ if (!assertChannel(soundChannel))
+ return;
+
+ debugC(5, kDebugSound, "DirectorSound::registerFade(): registered fading channel %d over %d ticks, startVol: %d, targetVol: %d, autostop: %d", soundChannel, ticks, startVol, targetVol, autoStop);
// sound enable is not working on fade sounds, so we just return directly when sounds are not enabling
if (!_enable)
@@ -269,10 +295,7 @@ void DirectorSound::registerFade(int soundChannel, bool fadeIn, int ticks) {
cancelFade(soundChannel);
- int startVol = fadeIn ? 0 : _channels[soundChannel]->volume;
- int targetVol = fadeIn ? _channels[soundChannel]->volume : 0;
-
- _channels[soundChannel]->fade = new FadeParams(startVol, targetVol, ticks, _window->getVM()->getMacTicks(), fadeIn);
+ _channels[soundChannel]->fade = new FadeParams(startVol, targetVol, ticks, _window->getVM()->getMacTicks(), targetVol > startVol, autoStop);
_mixer->setChannelVolume(_channels[soundChannel]->handle, startVol);
_channels[soundChannel]->volume = startVol;
@@ -288,6 +311,8 @@ bool DirectorSound::fadeChannels() {
fade->lapsedTicks = _window->getVM()->getMacTicks() - fade->startTicks;
if (fade->lapsedTicks > fade->totalTicks) {
+ if (fade->autoStop)
+ stopSound(it._key);
continue;
}
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 8c53c8fcca0..5c83acf65a6 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -47,9 +47,10 @@ struct FadeParams {
int startTicks;
int lapsedTicks;
bool fadeIn;
+ bool autoStop;
- FadeParams(int sv, int tv, int tt, int st, bool f) :
- startVol(sv), targetVol(tv), totalTicks(tt), startTicks(st), lapsedTicks(0), fadeIn(f) {}
+ FadeParams(int sv, int tv, int tt, int st, bool f, bool as) :
+ startVol(sv), targetVol(tv), totalTicks(tt), startTicks(st), lapsedTicks(0), fadeIn(f), autoStop(as) {}
};
const uint16 kMinSampledMenu = 10;
@@ -136,6 +137,8 @@ struct SoundChannel {
SoundID lastPlayedSound;
bool stopOnZero; // Should the sound be stopped when the channel contains cast member 0?
byte volume;
+ int pitchShiftPercent;
+ int originalRate;
FadeParams *fade;
// a non-zero sound ID if the channel is a puppet. i.e. it's controlled by lingo
@@ -150,7 +153,7 @@ struct SoundChannel {
// a stop at the end of a loop.
Audio::LoopableAudioStream *loopPtr;
- SoundChannel(): handle(), lastPlayedSound(SoundID()), stopOnZero(true), volume(255), fade(nullptr), puppet(SoundID()), newPuppet(false), movieChanged(false), loopPtr(nullptr) {}
+ SoundChannel(): handle(), lastPlayedSound(SoundID()), stopOnZero(true), volume(255), originalRate(-1), pitchShiftPercent(100), fade(nullptr), puppet(SoundID()), newPuppet(false), movieChanged(false), loopPtr(nullptr) {}
};
class DirectorSound {
@@ -200,7 +203,8 @@ public:
Common::String getCurrentSound() { return _currentSoundName; }
- void registerFade(int soundChannel, bool fadeIn, int ticks);
+ void registerFade(int soundChannel, int startVol, int targetVol, int ticks, bool autoStop = false);
+ void registerFade(int soundChannel, bool fadeIn, int ticks, bool autoStop = false);
bool fadeChannels();
bool isChannelActive(int soundChannel);
@@ -209,6 +213,7 @@ public:
void stopSound(int soundChannel);
void stopSound();
void setChannelDefaultVolume(int soundChannel);
+ void setChannelPitchShift(int soundChannel, int pitchShiftPercent);
private:
void setLastPlayedSound(int soundChannel, SoundID soundId, bool stopOnZero = true);
Commit: b0af6d4218744bd6410907aa081e2aef8812eb48
https://github.com/scummvm/scummvm/commit/b0af6d4218744bd6410907aa081e2aef8812eb48
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: XOBJ: Add VMPresent stub
Fixes start sequence of Dazzeloids.
Changed paths:
A engines/director/lingo/xlibs/vmpresent.cpp
A engines/director/lingo/xlibs/vmpresent.h
engines/director/lingo/lingo-object.cpp
engines/director/module.mk
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 20c6accfd4d..0a83ff1aea8 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -126,6 +126,7 @@
#include "director/lingo/xlibs/valkyrie.h"
#include "director/lingo/xlibs/videodiscxobj.h"
#include "director/lingo/xlibs/vmisonxfcn.h"
+#include "director/lingo/xlibs/vmpresent.h"
#include "director/lingo/xlibs/volumelist.h"
#include "director/lingo/xlibs/voyagerxsound.h"
#include "director/lingo/xlibs/widgetxobj.h"
@@ -325,6 +326,7 @@ static const struct XLibProto {
XLIBDEF(TenguXObj, kXObj, 400), // D4
XLIBDEF(TimextraXtra, kXtraObj, 500), // D5
XLIBDEF(UnitTestXObj, kXObj, 400), // D4
+ XLIBDEF(VMPresentXObj, kXObj, 400), // D4
XLIBDEF(VMisOnXFCN, kXObj, 400), // D4
XLIBDEF(ValkyrieXObj, kXObj, 400), // D4
XLIBDEF(VideodiscXObj, kXObj, 200), // D2
diff --git a/engines/director/lingo/xlibs/vmpresent.cpp b/engines/director/lingo/xlibs/vmpresent.cpp
new file mode 100644
index 00000000000..8e72d9d93cf
--- /dev/null
+++ b/engines/director/lingo/xlibs/vmpresent.cpp
@@ -0,0 +1,91 @@
+/* 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/vmpresent.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * dazzeloids
+ *
+ **************************************************/
+
+/*
+-- VMPresentObj v1.0
+I mNew --Instantiate the XObject
+I mVMPresent --Returns true (1) if VM is turned on, otherwise 0 (false)
+ */
+
+namespace Director {
+
+const char *VMPresentXObj::xlibName = "VMPresent";
+const XlibFileDesc VMPresentXObj::fileNames[] = {
+ { "VMPresent", nullptr },
+ { nullptr, nullptr },
+};
+
+static MethodProto xlibMethods[] = {
+ { "new", VMPresentXObj::m_new, 0, 0, 400 },
+ { "vMPresent", VMPresentXObj::m_vMPresent, 0, 0, 400 },
+ { nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+VMPresentXObject::VMPresentXObject(ObjectType ObjectType) :Object<VMPresentXObject>("VMPresent") {
+ _objType = ObjectType;
+}
+
+void VMPresentXObj::open(ObjectType type, const Common::Path &path) {
+ VMPresentXObject::initMethods(xlibMethods);
+ VMPresentXObject *xobj = new VMPresentXObject(type);
+ if (type == kXtraObj)
+ g_lingo->_openXtras.push_back(xlibName);
+ g_lingo->exposeXObject(xlibName, xobj);
+ g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void VMPresentXObj::close(ObjectType type) {
+ VMPresentXObject::cleanupMethods();
+ g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void VMPresentXObj::m_new(int nargs) {
+ g_lingo->printSTUBWithArglist("VMPresentXObj::m_new", nargs);
+ g_lingo->dropStack(nargs);
+ g_lingo->push(g_lingo->_state->me);
+}
+
+// Dazzeloids won't start unless virtual memory is disabled.
+// If another game uses this XObj, we might need to expand this into a title check.
+XOBJSTUB(VMPresentXObj::m_vMPresent, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/vmpresent.h b/engines/director/lingo/xlibs/vmpresent.h
new file mode 100644
index 00000000000..a4683fdd988
--- /dev/null
+++ b/engines/director/lingo/xlibs/vmpresent.h
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_VMPRESENT_H
+#define DIRECTOR_LINGO_XLIBS_VMPRESENT_H
+
+namespace Director {
+
+class VMPresentXObject : public Object<VMPresentXObject> {
+public:
+ VMPresentXObject(ObjectType objType);
+};
+
+namespace VMPresentXObj {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_vMPresent(int nargs);
+
+} // End of namespace VMPresentXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 87e969250b7..9070e179ae3 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -156,6 +156,7 @@ MODULE_OBJS = \
lingo/xlibs/valkyrie.o \
lingo/xlibs/videodiscxobj.o \
lingo/xlibs/vmisonxfcn.o \
+ lingo/xlibs/vmpresent.o \
lingo/xlibs/volumelist.o \
lingo/xlibs/voyagerxsound.o \
lingo/xlibs/widgetxobj.o \
Commit: df3c32da7b437b8074362fe3d10c88671e0e86f8
https://github.com/scummvm/scummvm/commit/df3c32da7b437b8074362fe3d10c88671e0e86f8
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-21T12:43:25+02:00
Commit Message:
DIRECTOR: Update detection entry for Puppet Motel
Changed paths:
engines/director/detection_tables.h
diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index e3a0be8c65b..e947fe5094a 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -7529,9 +7529,9 @@ static const DirectorGameDescription gameDescriptions[] = {
WINGAME1("princetonsat98", "", "sat98_32.exe", "1a7acbba10a7246ba58c1d53fc7203f5", 1446775, 501),
- // 1998 PC/Mac re-release
- MACGAME1("puppetmotel", "", "Puppet Motel Folder/Puppet Motel", "rt:04e7ccf432f8f968e6dd2282bf46c3a9", 812398, 501),
- WINGAME1("puppetmotel", "", "PUPPET/PUPPET.EXE", "t:c43660296f937be289ffaa593b47b4a1", 1434927, 501),
+ // 1998 PC/Mac re-release - box has yellow "New Release" marking
+ MACGAME1("puppetmotel", "New Release", "Puppet Motel Folder/Puppet Motel", "rt:04e7ccf432f8f968e6dd2282bf46c3a9", 812398, 501),
+ WINGAME1("puppetmotel", "New Release", "PUPPET/PUPPET.EXE", "t:c43660296f937be289ffaa593b47b4a1", 1434927, 501),
MACGAME1_l("putlestory", "", "PutlestorY", "552992fb31c736ca67ffd403096596d6", 720654, Common::JA_JPN, 501),
WINGAME1t_l("putlestory", "", "PUTLE32.EXE", "74c72ab0fcdb4c69114047c74cef486e", 1403206, Common::JA_JPN, 501),
More information about the Scummvm-git-logs
mailing list