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

ysj1173886760 42030331+ysj1173886760 at users.noreply.github.com
Mon Jul 19 02:53:58 UTC 2021


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

Summary:
d1abdb94be DIRECTOR: implement playFPlaySound in Director sound
0fd0588ab8 DIRECTOR: amend fplay in fplayxobj
876f998a05 DIRECTOR: check and play queued fplay sound in score. Amend the implementation of playFPlaySound
f15497f164 DIRECTOR: implement sound enabled for director sounds
1d4d0a2f39 DIRECTOR: implement setting and getting sound level in director sound
8d12017e78 DIRECTOR: implement the soundEnabled and the soundLevel.
8c58acc8d8 DIRECTOR: don't render if sprite type  is conflict with cast type, instead of override cast type
5f17f5e69b DIRECTOR: move checking the conflict of sprite type to where we create the widget.
9d6a7343da DIRECTOR: add a new parameter spriteType for createWidget.
eab6d53f15 DIRECTOR: add a util to check buton sprite
6d2131801f DIRECTOR: use sprite type to guide creating widget, instead of overwrite cast type
0a175742e1 DIRECTOR: amend setting hilite for text cast
da3f84e37a DIRECTOR: amend replacing widget for checking the changing of spriteType
d271a4d741 DIRECTOR: add comment for setClean


Commit: d1abdb94be5d6754edf8d6eca6386fd50e43ff75
    https://github.com/scummvm/scummvm/commit/d1abdb94be5d6754edf8d6eca6386fd50e43ff75
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: implement playFPlaySound in Director sound

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


diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index f21d5cc0ee..a3d9531db2 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -274,6 +274,67 @@ void DirectorSound::systemBeep() {
 	_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
 }
 
+void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayList) {
+
+	for (uint i = 0; i < fplayList.size(); i++)
+		_fplayQueue.push(fplayList[i]);
+
+	Common::String sndName = _fplayQueue.pop();
+	if (sndName.equalsIgnoreCase("stop")) {
+		stopSound(1);
+		_currentSoundName = "";
+
+		if (_fplayQueue.empty())
+			return;
+		else
+			sndName = _fplayQueue.pop();
+	}
+
+	uint32 tag = MKTAG('s', 'n', 'd', ' ');
+	uint id = 0xFFFF;
+	Archive *archive = nullptr;
+
+	// iterate opened ResFiles
+	for (Common::HashMap<Common::String, Archive *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::iterator it = g_director->_openResFiles.begin(); it != g_director->_openResFiles.end(); ++it) {
+		id = it->_value->findResourceID(tag, sndName, true);
+		if (id != 0xFFFF) {
+			archive = it->_value;
+			break;
+		}
+	}
+
+	if (id == 0xFFFF) {
+		warning("DirectorSound:playFPlaySound: can not find sound %s", sndName.c_str());
+		return;
+	}
+
+	Common::SeekableReadStreamEndian *sndData = archive->getResource(tag, id);
+	if (sndData != nullptr) {
+		SNDDecoder *ad = new SNDDecoder();
+		ad->loadStream(*sndData);
+		delete sndData;
+
+		Audio::AudioStream *as;
+		if (!_fplayQueue.empty() && _fplayQueue.front().equalsIgnoreCase("continuous")) {
+			_fplayQueue.pop();
+			as = ad->getLoopingAudioStream();
+		} else {
+			as = ad->getAudioStream();
+		}
+
+		if (!as) {
+			warning("DirectorSound:playFPlaySound: failed to get audio stream");
+			return;
+		}
+
+		// update current playing sound
+		_currentSoundName = sndName;
+
+		playStream(*as, 1);
+		delete ad;
+	}
+}
+
 Audio::AudioStream *AudioDecoder::getLoopingAudioStream() {
 	Audio::RewindableAudioStream *target = getAudioStream(DisposeAfterUse::YES);
 	if (!target)
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 1a160cb785..4d31ce0b6a 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -67,6 +67,10 @@ private:
 	Audio::PCSpeaker *_speaker;
 	Audio::SoundHandle _pcSpeakerHandle;
 
+	// these two were used in fplay xobj
+	Common::Queue<Common::String> _fplayQueue;
+	Common::String _currentSoundName;
+
 public:
 	DirectorSound(DirectorEngine *vm);
 	~DirectorSound();
@@ -77,8 +81,11 @@ public:
 	void playStream(Audio::AudioStream &stream, uint8 soundChannel);
 	void playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat = true);
 	void playExternalSound(AudioDecoder *ad, uint8 soundChannel, uint8 externalSoundID);
+	void playFPlaySound(const Common::Array<Common::String> &fplayList);
 	void systemBeep();
 
+	Common::String getCurrentSound() { return _currentSoundName; }
+
 	void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
 	bool fadeChannel(uint8 soundChannel);
 


Commit: 0fd0588ab8925658b8e7b8ea743c8f4a6b424b67
    https://github.com/scummvm/scummvm/commit/0fd0588ab8925658b8e7b8ea743c8f4a6b424b67
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: amend fplay in fplayxobj

Changed paths:
    engines/director/lingo/xlibs/fplayxobj.cpp


diff --git a/engines/director/lingo/xlibs/fplayxobj.cpp b/engines/director/lingo/xlibs/fplayxobj.cpp
index 3cf2a3bd30..699a39d6a1 100644
--- a/engines/director/lingo/xlibs/fplayxobj.cpp
+++ b/engines/director/lingo/xlibs/fplayxobj.cpp
@@ -28,9 +28,7 @@
   *************************************/
 
 #include "director/director.h"
-#include "director/archive.h"
 #include "director/sound.h"
-#include "director/util.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/xlibs/fplayxobj.h"
 
@@ -50,8 +48,6 @@ static BuiltinProto builtins[] = {
 	{ 0, 0, 0, 0, 0, VOIDSYM }
 };
 
-static char currentSound[20];
-
 void FPlayXObj::initialize(int type) {
 	if (!g_lingo->_builtinCmds.contains("FPlay")) {
 		g_lingo->initBuiltIns(builtins);
@@ -66,73 +62,13 @@ void FPlayXObj::b_fplay(int nargs) {
 		return;
 	}
 
-	if (nargs > 2) {
-		g_lingo->dropStack(nargs - 2);
-		warning("FPlayXObj::b_fplay: unhandled %d arguments", nargs - 2);
+	Common::Array<Common::String> arr(nargs);
+	for (int i = nargs - 1; i >= 0; i--) {
+		arr[i] = g_lingo->pop().asString();
 	}
 
-	Common::String mode;
-	if (nargs == 2)
-		mode = g_lingo->pop().asString();
-
-	bool loop = false;
-	if (!mode.empty()) {
-		if (mode.equalsIgnoreCase("continuous"))
-			loop = true;
-		else
-			warning("FPlayXObj::b_fplay: unhandled mode %s", mode.c_str());
-	}
-
-	Datum d = g_lingo->pop();
 	DirectorSound *sound = g_director->getSoundManager();
-	Common::String sndName = d.asString();
-
-	if (sndName.equalsIgnoreCase("stop")) {
-		sound->stopSound(1);
-		return;
-	}
-
-	uint32 tag = MKTAG('s', 'n', 'd', ' ');
-	uint id = 0xFFFF;
-	Archive *archive = nullptr;
-
-	// iterate opened ResFiles
-	for (Common::HashMap<Common::String, Archive *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::iterator it = g_director->_openResFiles.begin(); it != g_director->_openResFiles.end(); ++it) {
-		id = it->_value->findResourceID(tag, sndName, true);
-		if (id != 0xFFFF) {
-			archive = it->_value;
-			break;
-		}
-	}
-
-	if (id == 0xFFFF) {
-		warning("FPlayXObj::b_fplay: can not find sound %s", sndName.c_str());
-		return;
-	}
-
-	Common::SeekableReadStreamEndian *sndData = archive->getResource(tag, id);
-	if (sndData != nullptr) {
-		SNDDecoder *ad = new SNDDecoder();
-		ad->loadStream(*sndData);
-		delete sndData;
-
-		Audio::AudioStream *as;
-		if (loop)
-			as = ad->getLoopingAudioStream();
-		else
-			as = ad->getAudioStream();
-
-		if (!as) {
-			warning("FPlayXObj::b_fplay: failed to get audio stream");
-			return;
-		}
-
-		// update current playing sound
-		strcpy(currentSound, sndName.c_str());
-
-		sound->playStream(*as, 1);
-		delete ad;
-	}
+	sound->playFPlaySound(arr);
 }
 
 void FPlayXObj::b_sndinfo(int nargs) {
@@ -173,7 +109,7 @@ void FPlayXObj::b_fsound(int nargs) {
 
 	DirectorSound *sound = g_director->getSoundManager();
 	if (sound->isChannelActive(1)) {
-		g_lingo->push(Datum(Common::String(currentSound)));
+		g_lingo->push(Datum(sound->getCurrentSound()));
 	} else {
 		g_lingo->push(Datum("done"));
 	}


Commit: 876f998a05926ad24908ee30502e4eca38f04120
    https://github.com/scummvm/scummvm/commit/876f998a05926ad24908ee30502e4eca38f04120
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: check and play queued fplay sound in score. Amend the implementation of playFPlaySound

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


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 5bca1d170e..10e8d6fc3b 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -483,8 +483,11 @@ bool Score::renderFrame(uint16 frameId, RenderMode mode) {
 	if (_window->render())
 		updated = true;
 
+	// sound stuff
 	if (_frames[frameId]->_sound1.member || _frames[frameId]->_sound2.member)
 		playSoundChannel(frameId);
+	// this is currently only used in FPlayXObj
+	playQueuedSound();
 
 	if (_cursorDirty) {
 		renderCursor(_movie->getWindow()->getMousePos());
@@ -711,6 +714,11 @@ void Score::playSoundChannel(uint16 frameId) {
 	}
 }
 
+void Score::playQueuedSound() {
+	DirectorSound *sound = _vm->getSoundManager();
+	sound->playFPlaySound();
+}
+
 void Score::loadSampleSounds(uint type) {
 	// trying to load external sample sounds
 	// lazy loading
diff --git a/engines/director/score.h b/engines/director/score.h
index ba7cb0d79f..025060bd1b 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -116,6 +116,7 @@ private:
 	void update();
 
 	void playSoundChannel(uint16 frameId);
+	void playQueuedSound();
 
 	void screenShot();
 
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index a3d9531db2..a410aa7cc6 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -274,10 +274,12 @@ void DirectorSound::systemBeep() {
 	_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
 }
 
-void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayList) {
-
-	for (uint i = 0; i < fplayList.size(); i++)
-		_fplayQueue.push(fplayList[i]);
+void DirectorSound::playFPlaySound() {
+	if (_fplayQueue.empty())
+		return;
+	// only when the previous sound is finished, shall we play next one
+	if (isChannelActive(1))
+		return;
 
 	Common::String sndName = _fplayQueue.pop();
 	if (sndName.equalsIgnoreCase("stop")) {
@@ -335,6 +337,18 @@ void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayLis
 	}
 }
 
+void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayList) {
+
+	for (uint i = 0; i < fplayList.size(); i++)
+		_fplayQueue.push(fplayList[i]);
+
+	// stop the previous sound, because new one is comming
+	if (isChannelActive(1))
+		stopSound(1);
+
+	playFPlaySound();
+}
+
 Audio::AudioStream *AudioDecoder::getLoopingAudioStream() {
 	Audio::RewindableAudioStream *target = getAudioStream(DisposeAfterUse::YES);
 	if (!target)
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 4d31ce0b6a..b855879c40 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -82,6 +82,7 @@ public:
 	void playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat = true);
 	void playExternalSound(AudioDecoder *ad, uint8 soundChannel, uint8 externalSoundID);
 	void playFPlaySound(const Common::Array<Common::String> &fplayList);
+	void playFPlaySound();
 	void systemBeep();
 
 	Common::String getCurrentSound() { return _currentSoundName; }


Commit: f15497f164bd646aaf7fd31918fa8d503de01adf
    https://github.com/scummvm/scummvm/commit/f15497f164bd646aaf7fd31918fa8d503de01adf
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: implement sound enabled for director sounds

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


diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index a410aa7cc6..1e37a014ce 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -54,6 +54,8 @@ DirectorSound::DirectorSound(DirectorEngine *vm) : _vm(vm) {
 	_speaker = new Audio::PCSpeaker();
 	_mixer->playStream(Audio::Mixer::kSFXSoundType,
 		&_pcSpeakerHandle, _speaker, -1, 50, 0, DisposeAfterUse::NO, true);
+
+	_enable = true;
 }
 
 DirectorSound::~DirectorSound() {
@@ -75,24 +77,29 @@ void DirectorSound::playFile(Common::String filename, uint8 soundChannel) {
 	Audio::RewindableAudioStream *sound = af.getAudioStream(DisposeAfterUse::YES);
 
 	cancelFade(soundChannel);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, sound, -1, _channels[soundChannel - 1].volume);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, sound, -1, getChannelVolume(soundChannel));
 }
 
 void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to) {
 	Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(&stream);
 	Audio::SubSeekableAudioStream *subSeekStream = new Audio::SubSeekableAudioStream(seekStream, Audio::Timestamp(from, seekStream->getRate()), Audio::Timestamp(to, seekStream->getRate()));
 
+	// TODO: make sound enable settings work on this one
 	_mixer->stopHandle(_scriptSound);
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_scriptSound, subSeekStream);
 }
 
+uint8 DirectorSound::getChannelVolume(uint8 soundChannel) {
+	return _enable ? _channels[soundChannel - 1].volume : 0;
+}
+
 void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
 	if (!isChannelValid(soundChannel))
 		return;
 
 	cancelFade(soundChannel);
 	_mixer->stopHandle(_channels[soundChannel - 1].handle);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, &stream, -1, _channels[soundChannel - 1].volume);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, &stream, -1, getChannelVolume(soundChannel));
 }
 
 void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat) {
@@ -130,6 +137,14 @@ void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bo
 	}
 }
 
+void DirectorSound::setSoundEnabled(bool enabled) {
+	if (_enable == enabled)
+		return;
+	if (!enabled)
+		stopSound();
+	_enable = enabled;
+}
+
 void SNDDecoder::loadExternalSoundStream(Common::SeekableReadStreamEndian &stream) {
 	_size = stream.readUint32BE();
 
@@ -168,6 +183,10 @@ void DirectorSound::registerFade(uint8 soundChannel, bool fadeIn, int ticks) {
 	if (!isChannelValid(soundChannel))
 		return;
 
+	// sound enable is not working on fade sounds, so we just return directly when sounds are not enabling
+	if (!_enable)
+		return;
+
 	cancelFade(soundChannel);
 
 	int startVol = fadeIn ? 0 :  _channels[soundChannel - 1].volume;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index b855879c40..bc4cb1614c 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -71,6 +71,8 @@ private:
 	Common::Queue<Common::String> _fplayQueue;
 	Common::String _currentSoundName;
 
+	bool _enable;
+
 public:
 	DirectorSound(DirectorEngine *vm);
 	~DirectorSound();
@@ -83,8 +85,12 @@ public:
 	void playExternalSound(AudioDecoder *ad, uint8 soundChannel, uint8 externalSoundID);
 	void playFPlaySound(const Common::Array<Common::String> &fplayList);
 	void playFPlaySound();
+	void setSouldLevel(uint8 soundChannel, uint8 soundLevel);
+	void setSoundEnabled(bool enabled);
 	void systemBeep();
 
+	bool getSoundEnabled() { return _enable; }
+
 	Common::String getCurrentSound() { return _currentSoundName; }
 
 	void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
@@ -96,6 +102,7 @@ public:
 	void stopSound();
 
 private:
+	uint8 getChannelVolume(uint8 soundChannel);
 	bool isChannelValid(uint8 soundChannel);
 	void cancelFade(uint8 soundChannel);
 };


Commit: 1d4d0a2f39c2751c40f15becc2f5b31150148cba
    https://github.com/scummvm/scummvm/commit/1d4d0a2f39c2751c40f15becc2f5b31150148cba
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: implement setting and getting sound level in director sound

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


diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 1e37a014ce..16a9d1ba93 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -368,6 +368,31 @@ void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayLis
 	playFPlaySound();
 }
 
+void DirectorSound::setSoundLevelInternal(uint8 soundChannel, uint8 soundLevel) {
+	// we have 8 level of sounds, and in ScummVM, we have range 0 to 255, thus 1 level represent 32
+	_channels[soundChannel - 1].volume = soundLevel * 32;
+	if (_enable && isChannelActive(soundChannel))
+		_mixer->setChannelVolume(_channels[soundChannel - 1].handle, _channels[soundChannel - 1].volume);
+}
+
+// -1 represent all the sound channel
+void DirectorSound::setSouldLevel(int channel, uint8 soundLevel) {
+	if (channel != -1) {
+		if (!isChannelValid(channel))
+			return;
+		setSoundLevelInternal(channel, soundLevel);
+	} else {
+		for (uint i = 0; i < _channels.size(); i++)
+			setSoundLevelInternal(i + 1, soundLevel);
+	}
+}
+
+uint8 DirectorSound::getSoundLevel(uint8 soundChannel) {
+	if (!isChannelValid(soundChannel))
+		return 0;
+	return _channels[soundChannel - 1].volume / 32;
+}
+
 Audio::AudioStream *AudioDecoder::getLoopingAudioStream() {
 	Audio::RewindableAudioStream *target = getAudioStream(DisposeAfterUse::YES);
 	if (!target)
diff --git a/engines/director/sound.h b/engines/director/sound.h
index bc4cb1614c..46592a6986 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -85,7 +85,8 @@ public:
 	void playExternalSound(AudioDecoder *ad, uint8 soundChannel, uint8 externalSoundID);
 	void playFPlaySound(const Common::Array<Common::String> &fplayList);
 	void playFPlaySound();
-	void setSouldLevel(uint8 soundChannel, uint8 soundLevel);
+	void setSouldLevel(int channel, uint8 soundLevel);
+	uint8 getSoundLevel(uint8 soundChannel);
 	void setSoundEnabled(bool enabled);
 	void systemBeep();
 
@@ -103,6 +104,7 @@ public:
 
 private:
 	uint8 getChannelVolume(uint8 soundChannel);
+	void setSoundLevelInternal(uint8 soundChannel, uint8 soundLevel);
 	bool isChannelValid(uint8 soundChannel);
 	void cancelFade(uint8 soundChannel);
 };


Commit: 8d12017e78d63e936ea33962565e49e0a5b93e52
    https://github.com/scummvm/scummvm/commit/8d12017e78d63e936ea33962565e49e0a5b93e52
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: implement the soundEnabled and the soundLevel.

Changed paths:
    engines/director/lingo/lingo-the.cpp
    engines/director/sound.cpp


diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 6a15b2b8ee..58a3150dca 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -747,7 +747,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		d.u.i = (movie->_keyFlags & Common::KBD_SHIFT) ? 1 : 0;
 		break;
 	case kTheSoundEnabled:
-		getTheEntitySTUB(kTheSoundEnabled);
+		d.type = INT;
+		d.u.i = _vm->getSoundManager()->getSoundEnabled();
 		break;
 	case kTheSoundEntity:
 		{
@@ -768,7 +769,9 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		}
 		break;
 	case kTheSoundLevel:
-		getTheEntitySTUB(kTheSoundLevel);
+		// getting sound level of channel 1, maybe need to be amended in higher version
+		d.type = INT;
+		d.u.i = _vm->getSoundManager()->getSoundLevel(1);
 		break;
 	case kTheSprite:
 		d = getTheSprite(id, field);
@@ -1005,7 +1008,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 		}
 		break;
 	case kTheSoundEnabled:
-		setTheEntitySTUB(kTheSoundEnabled);
+		_vm->getSoundManager()->setSoundEnabled((bool)d.asInt());
 		break;
 	case kTheSoundEntity:
 		{
@@ -1025,7 +1028,8 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 		}
 		break;
 	case kTheSoundLevel:
-		setTheEntitySTUB(kTheSoundLevel);
+		// setting all of the channel for now
+		_vm->getSoundManager()->setSouldLevel(-1, d.asInt());
 		break;
 	case kTheSprite:
 		setTheSprite(id, field, d);
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 16a9d1ba93..e33ffe04eb 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -357,7 +357,6 @@ void DirectorSound::playFPlaySound() {
 }
 
 void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayList) {
-
 	for (uint i = 0; i < fplayList.size(); i++)
 		_fplayQueue.push(fplayList[i]);
 
@@ -377,6 +376,11 @@ void DirectorSound::setSoundLevelInternal(uint8 soundChannel, uint8 soundLevel)
 
 // -1 represent all the sound channel
 void DirectorSound::setSouldLevel(int channel, uint8 soundLevel) {
+	if (soundLevel >= 8) {
+		warning("DirectorSound::setSoundLevel: soundLevel %d out of bounds", soundLevel);
+		return;
+	}
+
 	if (channel != -1) {
 		if (!isChannelValid(channel))
 			return;


Commit: 8c58acc8d83dca54f2b3525dbeeadcc1a2d2c493
    https://github.com/scummvm/scummvm/commit/8c58acc8d83dca54f2b3525dbeeadcc1a2d2c493
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: don't render if sprite type  is conflict with cast type, instead of override cast type

Changed paths:
    engines/director/channel.cpp
    engines/director/sprite.cpp
    engines/director/sprite.h


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 8bed6669b3..1d15ead92b 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -87,7 +87,7 @@ DirectorPlotData Channel::getPlotData() {
 }
 
 Graphics::ManagedSurface *Channel::getSurface() {
-	if (_widget) {
+	if (_widget && _sprite->checkSpriteType()) {
 		return _widget->getSurface();
 	} else {
 		return nullptr;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 0df655aaf1..7f622f8467 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -187,6 +187,17 @@ void Sprite::setPattern(uint16 pattern) {
 	}
 }
 
+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) {
+		warning("Sprite::checkSpriteType: Didn't render sprite due to the sprite type mismatch with cast type");
+		return false;
+	}
+	return true;
+}
+
 void Sprite::setCast(CastMemberID memberID) {
 	/**
 	 * There are two things we need to take into account here:
@@ -249,17 +260,6 @@ void Sprite::setCast(CastMemberID memberID) {
 			_height = dims.height();
 		}
 
-		// 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) {
-			warning("Sprite::setCast(): sprite type doesn't match cast type, setting cast member to null");
-			// FIXME: We should still set the cast number but not render
-			// the sprite if the types conflict.
-			_cast = nullptr;
-			_castId = CastMemberID();
-		}
-
 	} else {
 		if (_castId.member != 0)
 			warning("Sprite::setCast(): %s is null", memberID.asString().c_str());
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 98575271b7..24308bb16f 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -70,6 +70,7 @@ public:
 	bool respondsToMouse();
 	bool isActive();
 	bool shouldHilite();
+	bool checkSpriteType();
 
 	uint16 getPattern();
 	void setPattern(uint16 pattern);


Commit: 5f17f5e69bb08a627931b2dd14f5fd4d119f9fb9
    https://github.com/scummvm/scummvm/commit/5f17f5e69bb08a627931b2dd14f5fd4d119f9fb9
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: move checking the conflict of sprite type to where we create the widget.

Changed paths:
    engines/director/channel.cpp


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 1d15ead92b..52eb2e97b2 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -87,7 +87,7 @@ DirectorPlotData Channel::getPlotData() {
 }
 
 Graphics::ManagedSurface *Channel::getSurface() {
-	if (_widget && _sprite->checkSpriteType()) {
+	if (_widget) {
 		return _widget->getSurface();
 	} else {
 		return nullptr;
@@ -490,6 +490,10 @@ void Channel::replaceWidget(CastMemberID previousCastId, bool force) {
 	}
 
 	if (_sprite && _sprite->_cast) {
+		// use sprite type to guide us how to draw the cast
+		// if the type don't match, then we will set it as transparent. i.e. don't create widget
+		if (!_sprite->checkSpriteType())
+			return;
 		Common::Rect bbox(getBbox());
 		_sprite->_cast->setModified(false);
 


Commit: 9d6a7343dabe068d5c0f866b0effb68e5c859a4d
    https://github.com/scummvm/scummvm/commit/9d6a7343dabe068d5c0f866b0effb68e5c859a4d
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: add a new parameter spriteType for createWidget.

Changed paths:
    engines/director/castmember.cpp
    engines/director/castmember.h
    engines/director/channel.cpp


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index 6f56217f51..e9304ffb94 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -175,7 +175,7 @@ BitmapCastMember::~BitmapCastMember() {
 		delete _matte;
 }
 
-Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel *channel) {
+Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) {
 	if (!_img) {
 		warning("BitmapCastMember::createWidget: No image decoder");
 		return nullptr;
@@ -419,7 +419,7 @@ void DigitalVideoCastMember::stopVideo(Channel *channel) {
 	debugC(2, kDebugImages, "STOPPING VIDEO %s", _filename.c_str());
 }
 
-Graphics::MacWidget *DigitalVideoCastMember::createWidget(Common::Rect &bbox, Channel *channel) {
+Graphics::MacWidget *DigitalVideoCastMember::createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) {
 	Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
 
 	_channel = channel;
@@ -728,7 +728,7 @@ void TextCastMember::importStxt(const Stxt *stxt) {
 	_ptext = stxt->_ptext;
 }
 
-Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *channel) {
+Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) {
 	Graphics::MacFont *macFont = new Graphics::MacFont(_fontId, _fontSize, _textSlant);
 	Graphics::MacWidget *widget = nullptr;
 	Common::Rect dims(bbox);
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index f7055167ff..c0fa645d9f 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -73,7 +73,7 @@ public:
 	virtual void setEditable(bool editable) {}
 	virtual bool isModified() { return _modified; }
 	virtual void setModified(bool modified) { _modified = modified; }
-	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel) { return nullptr; }
+	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) { return nullptr; }
 	virtual void updateWidget(Graphics::MacWidget *widget, Channel *channel) {}
 	virtual void updateFromWidget(Graphics::MacWidget *widget) {}
 	virtual Common::Rect getInitialRect() { return _initialRect; }
@@ -114,7 +114,7 @@ class BitmapCastMember : public CastMember {
 public:
 	BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint32 castTag, uint16 version, uint8 flags1 = 0);
 	~BitmapCastMember();
-	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel) override;
+	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
 
 	void createMatte(Common::Rect &bbox);
 	Graphics::Surface *getMatte(Common::Rect &bbox);
@@ -146,7 +146,7 @@ public:
 	~DigitalVideoCastMember();
 
 	virtual bool isModified() override;
-	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel) override;
+	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
 
 	bool loadVideo(Common::String path);
 	void startVideo(Channel *channel);
@@ -221,7 +221,7 @@ public:
 	virtual void setColors(uint32 *fgcolor, uint32 *bgcolor) override;
 
 	void setText(const Common::U32String &text);
-	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel) override;
+	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
 
 	virtual bool isEditable() override;
 	virtual void setEditable(bool editable) override;
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 52eb2e97b2..4b0b42fc7d 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -121,7 +121,7 @@ const Graphics::Surface *Channel::getMask(bool forceMatte) {
 		CastMember *member = g_director->getCurrentMovie()->getCastMember(maskID);
 
 		if (member && member->_initialRect == _sprite->_cast->_initialRect) {
-			Graphics::MacWidget *widget = member->createWidget(bbox, this);
+			Graphics::MacWidget *widget = member->createWidget(bbox, this, _sprite->_spriteType);
 			if (_mask)
 				delete _mask;
 			_mask = new Graphics::ManagedSurface();
@@ -497,7 +497,7 @@ void Channel::replaceWidget(CastMemberID previousCastId, bool force) {
 		Common::Rect bbox(getBbox());
 		_sprite->_cast->setModified(false);
 
-		_widget = _sprite->_cast->createWidget(bbox, this);
+		_widget = _sprite->_cast->createWidget(bbox, this, _sprite->_spriteType);
 		if (_widget) {
 			_widget->_priority = _priority;
 			_widget->draw();


Commit: eab6d53f156da56d99d8e99215028bfc2c8e723d
    https://github.com/scummvm/scummvm/commit/eab6d53f156da56d99d8e99215028bfc2c8e723d
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: add a util to check buton sprite

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


diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index b4acfdbb07..3187037b87 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -726,6 +726,10 @@ Common::Platform platformFromID(uint16 id) {
 	return Common::kPlatformUnknown;
 }
 
+bool isButtonSprite(SpriteType spriteType) {
+	return spriteType == kButtonSprite || spriteType == kCheckboxSprite || spriteType == kRadioButtonSprite;
+}
+
 Common::CodePage getEncoding(Common::Platform platform, Common::Language language) {
 	switch (language) {
 	case Common::JA_JPN:
diff --git a/engines/director/util.h b/engines/director/util.h
index 41055d2f98..85b246f09f 100644
--- a/engines/director/util.h
+++ b/engines/director/util.h
@@ -52,6 +52,8 @@ Common::String convertMacFilename(const char *name);
 
 Common::String dumpScriptName(const char *prefix, int type, int id, const char *ext);
 
+bool isButtonSprite(SpriteType spriteType);
+
 bool processQuitEvent(bool click = false); // events.cpp
 
 class RandomState {


Commit: 6d2131801f7ccf4aad5ab2e462d8bdd8d72cda75
    https://github.com/scummvm/scummvm/commit/6d2131801f7ccf4aad5ab2e462d8bdd8d72cda75
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: use sprite type to guide creating widget, instead of overwrite cast type

Changed paths:
    engines/director/castmember.cpp
    engines/director/channel.cpp
    engines/director/sprite.cpp


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index e9304ffb94..ee5d8a2acc 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -733,7 +733,17 @@ Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *c
 	Graphics::MacWidget *widget = nullptr;
 	Common::Rect dims(bbox);
 
-	switch (_type) {
+	CastType type = _type;
+	ButtonType buttonType;
+
+	// WORKAROUND: In D2/D3 there can be text casts that have button
+	// information set in the sprite.
+	if (type == kCastText && isButtonSprite(spriteType)) {
+		type = kCastButton;
+		buttonType = ButtonType(spriteType - 8);
+	}
+
+	switch (type) {
 	case kCastText:
 		// for mactext, we can expand now, but we can't shrink. so we may pass the small size when we have adjustToFit text style
 		if (_textType == kTextTypeAdjustToFit) {
@@ -758,7 +768,7 @@ Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *c
 	case kCastButton:
 		// note that we use _initialRect for the dimensions of the button;
 		// the values provided in the sprite bounding box are ignored
-		widget = new Graphics::MacButton(Graphics::MacButtonType(_buttonType), getAlignment(), g_director->getCurrentWindow(), bbox.left, bbox.top, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, getForeColor(), 0xff);
+		widget = new Graphics::MacButton(Graphics::MacButtonType(buttonType), getAlignment(), g_director->getCurrentWindow(), bbox.left, bbox.top, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, getForeColor(), 0xff);
 		widget->_focusable = true;
 
 		((Graphics::MacButton *)widget)->setHilite(_hilite);
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 4b0b42fc7d..f1c5cc95e0 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -387,11 +387,13 @@ void Channel::setEditable(bool editable) {
 void Channel::updateGlobalAttr() {
 	if (!_sprite->_cast)
 		return;
+
 	// update text info, including selEnd and selStart
 	if (_sprite->_cast->_type == kCastText && _sprite->_editable && _widget)
 		((Graphics::MacText *)_widget)->setSelRange(g_director->getCurrentMovie()->_selStart, g_director->getCurrentMovie()->_selEnd);
+
 	// update button info, including checkBoxType
-	if (_sprite->_cast->_type == kCastButton && _widget)
+	if ((_sprite->_cast->_type == kCastButton || isButtonSprite(_sprite->_spriteType)) && _widget)
 		((Graphics::MacButton *)_widget)->setCheckBoxType(g_director->getCurrentMovie()->_checkBoxType);
 }
 
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 7f622f8467..665a18b94f 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -233,19 +233,6 @@ void Sprite::setCast(CastMemberID memberID) {
 			}
 		}
 
-		if (_cast->_type == kCastText &&
-			(_spriteType == kButtonSprite ||
-				 _spriteType == kCheckboxSprite ||
-				 _spriteType == kRadioButtonSprite)) {
-			// WORKAROUND: In D2/D3 there can be text casts that have button
-			// information set in the sprite.
-			warning("Sprite::setCast(): Working around D2/3 button glitch");
-			// FIXME: We should not override the cast member's type here.
-			// We should only change how the sprite renders.
-			_cast->_type = kCastButton;
-			((TextCastMember *)_cast)->_buttonType = (ButtonType)(_spriteType - 8);
-		}
-
 		// TODO: Respect sprite width/height settings. Need to determine how to read
 		// them properly.
 		Common::Rect dims = _cast->getInitialRect();


Commit: 0a175742e1ccf2d6e791bee219f101e6dc8de2eb
    https://github.com/scummvm/scummvm/commit/0a175742e1ccf2d6e791bee219f101e6dc8de2eb
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:22+08:00

Commit Message:
DIRECTOR: amend setting hilite for text cast

Changed paths:
    engines/director/lingo/lingo-object.cpp


diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 342c519940..44f54d9600 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -937,11 +937,10 @@ bool TextCastMember::setField(int field, const Datum &d) {
 		return true;
 	case kTheHilite:
 		// TODO: Understand how texts can be selected programmatically as well.
-		if (_type == kCastButton) {
-			_hilite = (bool)d.asInt();
-			_modified = true;
-			return true;
-		}
+		// since hilite won't affect text castmember, and we may have button info in text cast in D2/3. so don't check type here
+		_hilite = (bool)d.asInt();
+		_modified = true;
+		return true;
 		break;
 	case kTheText:
 		setText(d.asString());


Commit: da3f84e37a5ef6fc369b8cab26acdf241773d305
    https://github.com/scummvm/scummvm/commit/da3f84e37a5ef6fc369b8cab26acdf241773d305
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:23+08:00

Commit Message:
DIRECTOR: amend replacing widget for checking the changing of spriteType

Changed paths:
    engines/director/castmember.cpp
    engines/director/channel.cpp


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index ee5d8a2acc..49db40ba32 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -734,7 +734,7 @@ Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *c
 	Common::Rect dims(bbox);
 
 	CastType type = _type;
-	ButtonType buttonType;
+	ButtonType buttonType = _buttonType;
 
 	// WORKAROUND: In D2/D3 there can be text casts that have button
 	// information set in the sprite.
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index f1c5cc95e0..a05a77c1a1 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -309,6 +309,9 @@ void Channel::setClean(Sprite *nextSprite, int spriteId, bool partial) {
 	// 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);
 
+	// 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;
+
 	if (nextSprite) {
 		if (nextSprite->_cast && (_dirty || _sprite->_castId != nextSprite->_castId)) {
 			if (nextSprite->_cast->_type == kCastDigitalVideo) {
@@ -335,7 +338,7 @@ void Channel::setClean(Sprite *nextSprite, int spriteId, bool partial) {
 
 	if (replace) {
 		_sprite->updateCast();
-		replaceWidget(previousCastId, dimsChanged);
+		replaceWidget(previousCastId, dimsChanged || spriteTypeChanged);
 	}
 
 	updateTextCast();


Commit: d271a4d7411bb85f272ed226c20ef07708058cff
    https://github.com/scummvm/scummvm/commit/d271a4d7411bb85f272ed226c20ef07708058cff
Author: ysj1173886760 (1173886760 at qq.com)
Date: 2021-07-19T10:41:23+08:00

Commit Message:
DIRECTOR: add comment for setClean

Changed paths:
    engines/director/channel.cpp


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index a05a77c1a1..63223d0433 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -336,6 +336,9 @@ void Channel::setClean(Sprite *nextSprite, int spriteId, bool partial) {
 		_delta = Common::Point(0, 0);
 	}
 
+	// FIXME: organize the logic here.
+	// for the dirty puppet sprites, we will always replaceWidget since previousCastId is 0, but we shouldn't replace the widget of there are only position changing
+	// e.g. we won't want a puppet editable text sprite changing because that will cause the loss of text.
 	if (replace) {
 		_sprite->updateCast();
 		replaceWidget(previousCastId, dimsChanged || spriteTypeChanged);




More information about the Scummvm-git-logs mailing list