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

sev- noreply at scummvm.org
Fri Jul 25 21:03:16 UTC 2025


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

Summary:
6332a507bc DIRECTOR: LINGO: Improve accuracy of b_sqrt
eecd61308e DIRECTOR: Make puppetSound(0) immediately stop audio
9d1410fc88 AUDIO: Add fader control for left and right channel outputs
bcf24cce8a DIRECTOR: XOBJ: Add pan and leftrightvol to VoyagerXSoundXObj


Commit: 6332a507bcd4bfa9bbe842431280a9002a661eb7
    https://github.com/scummvm/scummvm/commit/6332a507bcd4bfa9bbe842431280a9002a661eb7
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-25T23:03:11+02:00

Commit Message:
DIRECTOR: LINGO: Improve accuracy of b_sqrt

Fixes crash in plug room of Puppet Motel.

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/tests/math.lingo


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index f2c1f5723cd..dac1d45768d 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -513,7 +513,29 @@ void LB::b_sin(int nargs) {
 
 void LB::b_sqrt(int nargs) {
 	Datum d = g_lingo->pop();
-	Datum res(sqrt(d.asFloat()));
+	Datum res;
+	if (d.type == INT) {
+		// integer input returns the sqrt rounded to the nearest int
+		res = Datum((int)round(sqrt(d.asInt())));
+	} else if (d.type == FLOAT) {
+		// float input returns float output
+		res = Datum(sqrt(d.asFloat()));
+	} else if (d.type == STRING) {
+		// string input attempts to coerce to float, else crash
+		Common::String src = d.asString();
+		char *endPtr = nullptr;
+		double result = strtod(src.c_str(), &endPtr);
+		if (*endPtr == 0) {
+			res = Datum(sqrt(result));
+		} else {
+			g_lingo->lingoError("b_sqrt: Invalid string");
+		}
+	} else if (d.type == VOID) {
+		// void input returns float 0.0
+		res = Datum(0.0);
+	} else {
+		g_lingo->lingoError("b_sqrt: Invalid type");
+	}
 	g_lingo->push(res);
 }
 
diff --git a/engines/director/lingo/tests/math.lingo b/engines/director/lingo/tests/math.lingo
index 32548090165..3c2d8f1adf6 100644
--- a/engines/director/lingo/tests/math.lingo
+++ b/engines/director/lingo/tests/math.lingo
@@ -22,6 +22,32 @@ put (1024/4096)*100.0       -- 0.0
 put ((1024*1.0)/4096)*100.0 -- 25.0
 
 put the sqrt of 9
+scummvmAssertEqual(ilk(sqrt(EMPTY)), #float)
+scummvmAssertEqual(sqrt(EMPTY), 0.0)
+
+scummvmAssertEqual(ilk(sqrt(4)), #integer)
+scummvmAssertEqual(string(sqrt(0)), "0")
+scummvmAssertEqual(string(sqrt(4)), "2")
+scummvmAssertEqual(string(sqrt(5)), "2")
+scummvmAssertEqual(string(sqrt(8)), "3")
+
+scummvmAssertEqual(ilk(sqrt(4.0)), #float)
+scummvmAssertEqual(sqrt(0.0), 0.0)
+scummvmAssertEqual(sqrt(4.0), 2.0)
+scummvmAssertEqual(abs(sqrt(5.0) - 2.2361) < 0.0001, 1)
+scummvmAssertEqual(abs(sqrt(8.0) - 2.8284) < 0.0001, 1)
+
+scummvmAssertEqual(ilk(sqrt("4.0")), #float)
+scummvmAssertEqual(sqrt("0.0"), 0.0)
+scummvmAssertEqual(sqrt("4.0"), 2.0)
+scummvmAssertEqual(abs(sqrt("5.0") - 2.2361) < 0.0001, 1)
+scummvmAssertEqual(abs(sqrt("8.0") - 2.8284) < 0.0001, 1)
+
+scummvmAssertEqual(ilk(sqrt("4")), #float)
+scummvmAssertEqual(sqrt("0"), 0.0)
+scummvmAssertEqual(sqrt("4"), 2.0)
+scummvmAssertEqual(abs(sqrt("5") - 2.2361) < 0.0001, 1)
+scummvmAssertEqual(abs(sqrt("8") - 2.8284) < 0.0001, 1)
 
 -- Testing rounding
 set save to the scummvmVersion


Commit: eecd61308edd8de9b836a469cf211b4e6cd67597
    https://github.com/scummvm/scummvm/commit/eecd61308edd8de9b836a469cf211b4e6cd67597
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-25T23:03:11+02:00

Commit Message:
DIRECTOR: Make puppetSound(0) immediately stop audio

Fixes the slide after the final puzzle in Grackon's Curse,
which loops on soundBusy(1).

Changed paths:
    engines/director/sound.cpp
    engines/director/sound.h


diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 8d3772095e9..141153be21c 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -568,9 +568,13 @@ void DirectorSound::setPuppetSound(SoundID soundId, int soundChannel) {
 	if (!assertChannel(soundChannel))
 		return;
 
-	_channels[soundChannel]->newPuppet = true;
-	_channels[soundChannel]->puppet = soundId;
-	_channels[soundChannel]->stopOnZero = true;
+	if (soundId.isZero()) {
+		stopSound(soundChannel);
+	} else {
+		_channels[soundChannel]->newPuppet = true;
+		_channels[soundChannel]->puppet = soundId;
+		_channels[soundChannel]->stopOnZero = true;
+	}
 }
 
 void DirectorSound::playPuppetSound(int soundChannel) {
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 1ef0f8cb78f..1357940896b 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -130,6 +130,11 @@ struct SoundID {
 	bool operator!=(const SoundID &b) {
 		return !(*this == b);
 	}
+	bool isZero() {
+		if (type == kSoundCast)
+			return u.cast.member == 0;
+		return false;
+	}
 };
 
 struct SoundChannel {


Commit: 9d1410fc881daa50e633922e25e7f5476e9ac336
    https://github.com/scummvm/scummvm/commit/9d1410fc881daa50e633922e25e7f5476e9ac336
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-25T23:03:11+02:00

Commit Message:
AUDIO: Add fader control for left and right channel outputs

Changed paths:
    audio/mixer.cpp
    audio/mixer.h
    audio/mixer_intern.h


diff --git a/audio/mixer.cpp b/audio/mixer.cpp
index ec3ffeeac2d..4791628bbac 100644
--- a/audio/mixer.cpp
+++ b/audio/mixer.cpp
@@ -114,24 +114,52 @@ public:
 	 */
 	int8 getBalance();
 
+	/**
+	 * Sets the channel's left fader level.
+	 *
+	 * @param faderL The channel's new left fader level, in the range of 0-255.
+	 */
+	void setFaderL(uint8 faderL);
+
+	/**
+	 * Get the channel's left fader level.
+	 *
+	 * @return The channel's left fader level.
+	 */
+	uint8 getFaderL();
+
+	/**
+	 * Sets the channel's right fader level.
+	 *
+	 * @param faderL The channel's new right fader level, in the range of 0-255.
+	 */
+	void setFaderR(uint8 faderR);
+
+	/**
+	 * Get the channel's right fader level.
+	 *
+	 * @return The channel's right fader level.
+	 */
+	uint8 getFaderR();
+
 	/**
 	 * Set the channel's sample rate.
-	 * 
+	 *
 	 * @param rate	The new sample rate. Must be less than 131072
-	*/
+	 */
 	void setRate(uint32 rate);
 
 	/**
 	 * Get the channel's sample rate.
-	 * 
+	 *
 	 * @return The current sample rate of the channel.
-	*/
+	 */
 	uint32 getRate();
 
 	/**
 	 * Reset the sample rate of the channel back to its
 	 * AudioStream's native rate.
-	*/
+	 */
 	void resetRate();
 
 	/**
@@ -176,6 +204,8 @@ private:
 
 	byte _volume;
 	int8 _balance;
+	uint8 _faderL;
+	uint8 _faderR;
 
 	void updateChannelVolumes();
 	st_volume_t _volL, _volR;
@@ -421,6 +451,42 @@ int8 MixerImpl::getChannelBalance(SoundHandle handle) {
 	return _channels[index]->getBalance();
 }
 
+void MixerImpl::setChannelFaderL(SoundHandle handle, uint8 faderL) {
+	Common::StackLock lock(_mutex);
+
+	const int index = handle._val % NUM_CHANNELS;
+	if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
+		return;
+
+	_channels[index]->setFaderL(faderL);
+}
+
+uint8 MixerImpl::getChannelFaderL(SoundHandle handle) {
+	const int index = handle._val % NUM_CHANNELS;
+	if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
+		return 0;
+
+	return _channels[index]->getFaderL();
+}
+
+void MixerImpl::setChannelFaderR(SoundHandle handle, uint8 faderR) {
+	Common::StackLock lock(_mutex);
+
+	const int index = handle._val % NUM_CHANNELS;
+	if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
+		return;
+
+	_channels[index]->setFaderR(faderR);
+}
+
+uint8 MixerImpl::getChannelFaderR(SoundHandle handle) {
+	const int index = handle._val % NUM_CHANNELS;
+	if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
+		return 0;
+
+	return _channels[index]->getFaderR();
+}
+
 void MixerImpl::setChannelRate(SoundHandle handle, uint32 rate) {
 	Common::StackLock lock(_mutex);
 
@@ -435,7 +501,7 @@ uint32 MixerImpl::getChannelRate(SoundHandle handle) {
 	const int index = handle._val % NUM_CHANNELS;
 	if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
 		return 0;
-	
+
 	return _channels[index]->getRate();
 }
 
@@ -445,7 +511,7 @@ void MixerImpl::resetChannelRate(SoundHandle handle) {
 	const int index = handle._val % NUM_CHANNELS;
 	if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
 		return;
-	
+
 	_channels[index]->resetRate();
 }
 
@@ -575,7 +641,7 @@ int MixerImpl::getVolumeForSoundType(SoundType type) const {
 Channel::Channel(Mixer *mixer, Mixer::SoundType type, AudioStream *stream,
 				 DisposeAfterUse::Flag autofreeStream, bool reverseStereo, int id, bool permanent)
 	: _type(type), _mixer(mixer), _id(id), _permanent(permanent), _volume(Mixer::kMaxChannelVolume),
-	  _balance(0), _pauseLevel(0), _samplesConsumed(0), _samplesDecoded(0), _mixerTimeStamp(0),
+	  _balance(0), _faderL(255), _faderR(255), _pauseLevel(0), _samplesConsumed(0), _samplesDecoded(0), _mixerTimeStamp(0),
 	  _pauseStartTime(0), _pauseTime(0), _converter(nullptr), _volL(0), _volR(0),
 	  _stream(stream, autofreeStream) {
 	assert(mixer);
@@ -607,6 +673,24 @@ int8 Channel::getBalance() {
 	return _balance;
 }
 
+void Channel::setFaderL(uint8 faderL) {
+	_faderL = faderL;
+	updateChannelVolumes();
+}
+
+uint8 Channel::getFaderL() {
+	return _faderL;
+}
+
+void Channel::setFaderR(uint8 faderR) {
+	_faderR = faderR;
+	updateChannelVolumes();
+}
+
+uint8 Channel::getFaderR() {
+	return _faderR;
+}
+
 void Channel::setRate(uint32 rate) {
 	if (_converter)
 		_converter->setInputRate(rate);
@@ -615,7 +699,7 @@ void Channel::setRate(uint32 rate) {
 uint32 Channel::getRate() {
 	if (_converter)
 		return _converter->getInputRate();
-	
+
 	return 0;
 }
 
@@ -647,6 +731,8 @@ void Channel::updateChannelVolumes() {
 			_volL = ((127 - _balance) * vol) / (Mixer::kMaxChannelVolume * 127);
 			_volR = vol / Mixer::kMaxChannelVolume;
 		}
+		_volL = (st_volume_t)((int)_volL * (int)_faderL / 255);
+		_volR = (st_volume_t)((int)_volR * (int)_faderR / 255);
 	} else {
 		_volL = _volR = 0;
 	}
diff --git a/audio/mixer.h b/audio/mixer.h
index 8cfdca80345..bb5be27bc52 100644
--- a/audio/mixer.h
+++ b/audio/mixer.h
@@ -129,7 +129,7 @@ public:
 
 	/**
 	 * Stop all currently playing sounds.
-	 */
+	*/
 	virtual void stopAll() = 0;
 
 	/**
@@ -252,6 +252,40 @@ public:
 	 */
 	virtual int8 getChannelBalance(SoundHandle handle) = 0;
 
+	/**
+	 * Set the channel's left fader level for the given handle.
+	 *
+	 * @param handle   The sound to affect.
+	 * @param faderL  The channel's new left fader level, in the range of 0-255.
+	 */
+	virtual void setChannelFaderL(SoundHandle handle, uint8 faderL) = 0;
+
+	/**
+	 * Get the channel's left fader level for the given handle.
+	 *
+	 * @param handle  The sound to affect.
+	 *
+	 * @return The channel's left fader level.
+	 */
+	virtual uint8 getChannelFaderL(SoundHandle handle) = 0;
+
+	/**
+	 * Set the channel's right fader level for the given handle.
+	 *
+	 * @param handle   The sound to affect.
+	 * @param faderR  The channel's new right fader level, in the range of 0-255.
+	 */
+	virtual void setChannelFaderR(SoundHandle handle, uint8 faderR) = 0;
+
+	/**
+	 * Get the channel's right fader level for the given handle.
+	 *
+	 * @param handle  The sound to affect.
+	 *
+	 * @return The channel's right fader level.
+	 */
+	virtual uint8 getChannelFaderR(SoundHandle handle) = 0;
+
 	/**
 	 * Set the sample rate for the given handle.
 	 *
diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h
index 18a0d97f176..f365af0f175 100644
--- a/audio/mixer_intern.h
+++ b/audio/mixer_intern.h
@@ -118,6 +118,10 @@ public:
 	virtual byte getChannelVolume(SoundHandle handle);
 	virtual void setChannelBalance(SoundHandle handle, int8 balance);
 	virtual int8 getChannelBalance(SoundHandle handle);
+	virtual void setChannelFaderL(SoundHandle handle, uint8 scaleL);
+	virtual uint8 getChannelFaderL(SoundHandle handle);
+	virtual void setChannelFaderR(SoundHandle handle, uint8 scaleR);
+	virtual uint8 getChannelFaderR(SoundHandle handle);
 	virtual void setChannelRate(SoundHandle handle, uint32 rate);
 	virtual uint32 getChannelRate(SoundHandle handle);
 	virtual void resetChannelRate(SoundHandle handle);


Commit: bcf24cce8a4fb7dcbefb628b230a7217bd35b073
    https://github.com/scummvm/scummvm/commit/bcf24cce8a4fb7dcbefb628b230a7217bd35b073
Author: Scott Percival (code at moral.net.au)
Date: 2025-07-25T23:03:11+02:00

Commit Message:
DIRECTOR: XOBJ: Add pan and leftrightvol to VoyagerXSoundXObj

Fixes various audio effects 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 0df3c6ea877..d8b8e30458d 100644
--- a/engines/director/lingo/xlibs/voyagerxsound.cpp
+++ b/engines/director/lingo/xlibs/voyagerxsound.cpp
@@ -177,6 +177,15 @@ void VoyagerXSoundXObject::volume(int chan, int vol) {
 	_soundManager->setChannelVolume(channelID, vol);
 }
 
+void VoyagerXSoundXObject::leftrightvol(int chan, uint8 lvol, uint8 rvol) {
+	if (!_channels.contains(chan)) {
+		return;
+	}
+	int channelID = _channels[chan]->channelID;
+	_soundManager->setChannelFaderL(channelID, lvol);
+	_soundManager->setChannelFaderR(channelID, lvol);
+}
+
 void VoyagerXSoundXObject::frequency(int chan, int percent) {
 	if (!_channels.contains(chan)) {
 		return;
@@ -185,6 +194,16 @@ void VoyagerXSoundXObject::frequency(int chan, int percent) {
 	_soundManager->setChannelPitchShift(channelID, percent);
 }
 
+void VoyagerXSoundXObject::pan(int chan, int percent) {
+	if (!_channels.contains(chan)) {
+		return;
+	}
+	percent = MAX(MIN(100, percent), -100);
+	int channelID = _channels[chan]->channelID;
+	_soundManager->setChannelBalance(channelID, (int8)percent);
+}
+
+
 void VoyagerXSoundXObj::open(ObjectType type, const Common::Path &path) {
     VoyagerXSoundXObject::initMethods(xlibMethods);
     VoyagerXSoundXObject *xobj = new VoyagerXSoundXObject(type);
@@ -299,7 +318,16 @@ void VoyagerXSoundXObj::m_volume(int nargs) {
 	g_lingo->push(Datum(1));
 }
 
-XOBJSTUB(VoyagerXSoundXObj::m_leftrightvol, 0)
+void VoyagerXSoundXObj::m_leftrightvol(int nargs) {
+	g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_pan", nargs);
+	VoyagerXSoundXObject *me = static_cast<VoyagerXSoundXObject *>(g_lingo->_state->me.u.obj);
+	ARGNUMCHECK(3);
+	int rvol = g_lingo->pop().asInt();
+	int lvol = g_lingo->pop().asInt();
+	int chan = g_lingo->pop().asInt();
+	me->leftrightvol(chan, (uint8)lvol, (uint8)rvol);
+	g_lingo->push(Datum(1));
+}
 
 void VoyagerXSoundXObj::m_fade(int nargs) {
 	g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_fade", nargs);
@@ -342,7 +370,17 @@ void VoyagerXSoundXObj::m_frequency(int nargs) {
 }
 
 
-XOBJSTUB(VoyagerXSoundXObj::m_pan, 0)
+void VoyagerXSoundXObj::m_pan(int nargs) {
+	g_lingo->printSTUBWithArglist("VoyagerXSoundXObj::m_pan", 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->pan(chan, percent);
+	g_lingo->push(Datum(1));
+}
+
+
 XOBJSTUB(VoyagerXSoundXObj::m_startrecord, 0)
 XOBJSTUB(VoyagerXSoundXObj::m_stoprecord, 0)
 XOBJSTUB(VoyagerXSoundXObj::m_recordpath, 0)
diff --git a/engines/director/lingo/xlibs/voyagerxsound.h b/engines/director/lingo/xlibs/voyagerxsound.h
index b40e9f227d4..52790dd5dfb 100644
--- a/engines/director/lingo/xlibs/voyagerxsound.h
+++ b/engines/director/lingo/xlibs/voyagerxsound.h
@@ -42,7 +42,9 @@ public:
 	int fade(int chan, int endvol, int duration, bool autostop);
 	void stop(int chan);
 	void volume(int chan, int vol);
+	void leftrightvol(int chan, uint8 lvol, uint8 rvol);
 	void frequency(int chan, int percent);
+	void pan(int chan, int percent);
 
 	DirectorSound *_soundManager;
 
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 141153be21c..ffe34116464 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -698,6 +698,44 @@ void DirectorSound::setChannelVolume(int channel, uint8 volume) {
 	}
 }
 
+void DirectorSound::setChannelBalance(int channel, int8 balance) {
+	if (!assertChannel(channel))
+		return;
+	_mixer->setChannelBalance(_channels[channel]->handle, balance);
+}
+
+int8 DirectorSound::getChannelBalance(int channel) {
+	if (!assertChannel(channel))
+		return 0;
+	return _mixer->getChannelBalance(_channels[channel]->handle);
+}
+
+void DirectorSound::setChannelFaderL(int channel, uint8 faderL) {
+	if (!assertChannel(channel))
+		return;
+	_mixer->setChannelFaderL(_channels[channel]->handle, faderL);
+}
+
+uint8 DirectorSound::getChannelFaderL(int channel) {
+	if (!assertChannel(channel))
+		return 0;
+	return _mixer->getChannelFaderL(_channels[channel]->handle);
+}
+
+void DirectorSound::setChannelFaderR(int channel, uint8 faderR) {
+	if (!assertChannel(channel))
+		return;
+	_mixer->setChannelFaderR(_channels[channel]->handle, faderR);
+}
+
+uint8 DirectorSound::getChannelFaderR(int channel) {
+	if (!assertChannel(channel))
+		return 0;
+	return _mixer->getChannelFaderR(_channels[channel]->handle);
+}
+
+
+
 SNDDecoder::SNDDecoder()
 		: AudioDecoder() {
 	_data = nullptr;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 1357940896b..56bef9dd708 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -214,6 +214,12 @@ public:
 	bool isChannelActive(int soundChannel);
 	uint8 getChannelVolume(int soundChannel);
 	void setChannelVolume(int channel, uint8 volume);
+	int8 getChannelBalance(int soundChannel);
+	void setChannelBalance(int soundChannel, int8 balance);
+	uint8 getChannelFaderL(int soundChannel);
+	void setChannelFaderL(int soundChannel, uint8 faderL);
+	uint8 getChannelFaderR(int soundChannel);
+	void setChannelFaderR(int soundChannel, uint8 faderR);
 	void stopSound(int soundChannel);
 	void stopSound();
 	void setChannelDefaultVolume(int soundChannel);




More information about the Scummvm-git-logs mailing list