[Scummvm-git-logs] scummvm master -> 59d6c5e5fd0daeeb48f93034a8132949b0145ace

moralrecordings code at moral.net.au
Sat Mar 21 15:40:41 UTC 2020


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

Summary:
d36d0473d9 DIRECTOR: Implement loading for SND data
e68f7eebab DIRECTOR: Fix loading cast names with 13 letters
3382e3e965 DIRECTOR: LINGO: Add helper for fetching cast ID from a Datum
59d6c5e5fd DIRECTOR: Fix audio lifetime, implement b_puppetSound


Commit: d36d0473d9634dc3702dc3772161cd2d87e09a55
    https://github.com/scummvm/scummvm/commit/d36d0473d9634dc3702dc3772161cd2d87e09a55
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:37:50+08:00

Commit Message:
DIRECTOR: Implement loading for SND data

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


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 14e39e2627..e78e5323c9 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -121,6 +121,18 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16
 	_tag = castTag;
 }
 
+SoundCast::SoundCast(Common::ReadStreamEndian &stream, uint16 version) {
+	_type = kCastSound;
+	_audio = nullptr;
+
+	if (version == 4) {
+		for (int i = 0; i < 0xe; i++) {
+			stream.readByte();
+		}
+		_looping = stream.readByte() & 0x10;
+	}
+}
+
 TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version, int32 bgcolor) {
 	_type = kCastText;
 
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 954b38d73d..caa564776b 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -30,6 +30,10 @@ namespace Graphics {
 struct Surface;
 }
 
+namespace Audio {
+struct SeekableAudioStream;
+}
+
 namespace Common {
 class SeekableReadStream;
 class ReadStreamEndian;
@@ -71,6 +75,14 @@ public:
 	uint32 _tag;
 };
 
+class SoundCast : public Cast {
+public:
+	SoundCast(Common::ReadStreamEndian &stream, uint16 version);
+
+	bool _looping;
+	Audio::SeekableAudioStream *_audio;
+};
+
 class ShapeCast : public Cast {
 public:
 	ShapeCast(Common::ReadStreamEndian &stream, uint16 version);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 82d001a57a..f856a32b5d 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -26,6 +26,7 @@
 #include "common/memstream.h"
 #include "common/substream.h"
 
+#include "audio/decoders/raw.h"
 #include "engines/util.h"
 #include "graphics/primitives.h"
 #include "graphics/macgui/macfontmanager.h"
@@ -243,11 +244,6 @@ void Score::loadArchive() {
 		debug("STUB: Unhandled 'PICT' resource");
 	}
 
-	// Sound resources
-	if (_movieArchive->hasResource(MKTAG('s', 'n', 'd', ' '), -1)) {
-		debug("STUB: Unhandled 'snd ' resource");
-	}
-
 	// Film Loop resources
 	if (_movieArchive->hasResource(MKTAG('S', 'C', 'V', 'W'), -1)) {
 		debug("STUB: Unhandled 'SCVW' resource");
@@ -256,6 +252,7 @@ void Score::loadArchive() {
 
 	setSpriteCasts();
 	loadSpriteImages(false);
+	loadSpriteSounds(false);
 
 	// Now process STXTs
 	Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
@@ -375,6 +372,43 @@ void Score::loadSpriteImages(bool isSharedCast) {
 	}
 }
 
+void Score::loadSpriteSounds(bool isSharedCast) {
+	debugC(1, kDebugLoading, "****** Preloading sprite sounds");
+
+	for (Common::HashMap<int, Cast *>::iterator c = _loadedCast->begin(); c != _loadedCast->end(); ++c) {
+		if (!c->_value)
+			continue;
+
+		if (c->_value->_type != kCastSound)
+			continue;
+
+		SoundCast *soundCast = (SoundCast *)c->_value;
+		uint32 tag = MKTAG('s', 'n', 'd', ' ');
+		uint16 sndId = (uint16)(c->_key + _castIDoffset);
+
+		if (_vm->getVersion() >= 4 && soundCast->_children.size() > 0) {
+			sndId = soundCast->_children[0].index;
+			tag = soundCast->_children[0].tag;
+		}
+
+		Common::SeekableSubReadStreamEndian *sndData = NULL;
+
+		switch (tag) {
+		case MKTAG('s', 'n', 'd', ' '):
+			if (_movieArchive->hasResource(MKTAG('s', 'n', 'd', ' '), sndId)) {
+				debugC(2, kDebugLoading, "****** Loading 'snd ' id: %d", sndId);
+				sndData = _movieArchive->getResource(MKTAG('s', 'n', 'd', ' '), sndId);
+			}
+			break;
+		}
+
+		if (sndData != NULL && soundCast != NULL) {
+			Audio::SeekableAudioStream *audio = makeSNDStream(sndData);
+			soundCast->_audio = audio;
+		}
+	}
+}
+
 
 Score::~Score() {
 	if (_surface && _surface->w)
@@ -741,6 +775,10 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastBitmap (%d children)", res->children.size());
 		_loadedCast->setVal(id, new BitmapCast(castStream, res->tag, _vm->getVersion()));
 		break;
+	case kCastSound:
+		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastSound (%d children)", res->children.size());
+		_loadedCast->setVal(id, new SoundCast(castStream, _vm->getVersion()));
+		break;
 	case kCastText:
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastText (%d children)", res->children.size());
 		_loadedCast->setVal(id, new TextCast(castStream, _vm->getVersion(), _stageColor));
@@ -773,10 +811,6 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		warning("STUB: Score::loadCastData(): kCastPicture (%d children)", res->children.size());
 		size2 = 0;
 		break;
-	case kCastSound:
-		warning("STUB: Score::loadCastData(): kCastSound (%d children)", res->children.size());
-		size2 = 0;
-		break;
 	case kCastMovie:
 		warning("STUB: Score::loadCastData(): kCastMovie (%d children)", res->children.size());
 		size2 = 0;
diff --git a/engines/director/score.h b/engines/director/score.h
index 9b798b60c1..4ed654722f 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -89,6 +89,7 @@ public:
 	Sprite *getSpriteById(uint16 id);
 	void setSpriteCasts();
 	void loadSpriteImages(bool isSharedCast);
+	void loadSpriteSounds(bool isSharedCast);
 	void copyCastStxts();
 	Graphics::ManagedSurface *getSurface() { return _surface; }
 
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 95939e49c3..86399ca8fb 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -21,12 +21,15 @@
  */
 
 #include "common/file.h"
+#include "common/substream.h"
 
 #include "audio/decoders/wave.h"
+#include "audio/decoders/raw.h"
 #include "audio/mixer.h"
 #include "audio/softsynth/pcspk.h"
 #include "audio/decoders/aiff.h"
 
+#include "director/director.h"
 #include "director/sound.h"
 
 namespace Director {
@@ -92,6 +95,14 @@ void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to)
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, _scriptSound, subSeekStream);
 }
 
+void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
+	Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(&stream);
+	if (soundChannel == 1)
+		_mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, seekStream);
+	else
+		_mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, seekStream);
+}
+
 bool DirectorSound::isChannelActive(uint8 channelID) {
 	if (channelID == 1) {
 		return _mixer->isSoundHandleActive(*_sound1);
@@ -114,4 +125,56 @@ void DirectorSound::systemBeep() {
 	_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
 }
 
+
+Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream) {
+	if (debugChannelSet(5, kDebugLoading)) {
+		debugC(5, kDebugLoading, "snd header:");
+		stream->hexdump(0x4e);
+	}
+
+	// unk1
+	for (uint32 i = 0; i < 0x14; i++) {
+		stream->readByte();
+	}
+	uint16 channels = stream->readUint16();
+	if (channels != 1 || channels != 2) {
+		warning("STUB: loadSpriteSounds: no support for old sound format");
+		return NULL;
+	}
+	uint16 rate = stream->readUint16();
+
+	// unk2
+	for (uint32 i = 0; i < 0x06; i++) {
+		stream->readByte();
+	}
+	uint32 length = stream->readUint32();
+	/*uint16 unk3 =*/stream->readUint16();
+	/*uint32 length_copy =*/stream->readUint32();
+	/*uint8 unk4 =*/stream->readByte();
+	/*uint8 unk5 =*/stream->readByte();
+	/*uint16 unk6 =*/stream->readUint16();
+	// unk7
+	for (uint32 i = 0; i < 0x12; i++) {
+		stream->readByte();
+	}
+	uint16 bits = stream->readUint16();
+	// unk8
+	for (uint32 i = 0; i < 0x0c; i++) {
+		stream->readByte();
+	}
+
+	byte flags = 0;
+	flags |= channels == 2 ? Audio::FLAG_STEREO : 0;
+	flags |= bits == 16 ? Audio::FLAG_16BITS : 0;
+	flags |= bits == 8 ? Audio::FLAG_UNSIGNED : 0;
+	uint32 size = length * channels * (bits == 16 ? 2 : 1);
+
+	byte *data = (byte *)malloc(size);
+	assert(data);
+	stream->read(data, size);
+
+	return Audio::makeRawStream(data, size, rate, flags);
+}
+
+
 } // End of namespace Director
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 1205a9f8ef..2942ddd4a1 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -27,6 +27,7 @@ namespace Audio {
 	class AudioStream;
 	class SoundHandle;
 	class PCSpeaker;
+	class SeekableAudioStream;
 }
 
 namespace Director {
@@ -48,11 +49,14 @@ public:
 	void playWAV(Common::String filename, uint8 channelID);
 	void playAIFF(Common::String filename, uint8 channelID);
 	void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
+	void playStream(Audio::AudioStream &stream, uint8 soundChannel);
 	void systemBeep();
 	bool isChannelActive(uint8 channelID);
 	void stopSound();
 };
 
+Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream);
+
 } // End of namespace Director
 
 #endif


Commit: e68f7eebab6a0ff838b38e6e3fcf37f421117c8a
    https://github.com/scummvm/scummvm/commit/e68f7eebab6a0ff838b38e6e3fcf37f421117c8a
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:37:50+08:00

Commit Message:
DIRECTOR: Fix loading cast names with 13 letters

Changed paths:
    engines/director/score.cpp


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index f856a32b5d..becdb55c84 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1369,10 +1369,10 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
 	for (uint16 i = 0; i < count - 1; i++) {
 		Common::String entryString;
 
-		for (uint j = entries[i]; j < entries[i + 1]; j++)
+		for (uint j = entries[i] + 1; j < entries[i + 1]; j++) // Skip first byte which is string length
 			if (data[j] == '\r')
 				entryString += '\n';
-			else if (j > entries[i] || data[j] >= 0x20) // Skip first byte which is string length
+			else if (data[j] >= 0x20)
 				entryString += data[j];
 
 		strings.push_back(entryString);


Commit: 3382e3e965e4aa8f4ce8b3a5b077a2a8183238ae
    https://github.com/scummvm/scummvm/commit/3382e3e965e4aa8f4ce8b3a5b077a2a8183238ae
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:37:50+08:00

Commit Message:
DIRECTOR: LINGO: Add helper for fetching cast ID from a Datum

Changed paths:
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 76be97806a..36d7601474 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -485,6 +485,32 @@ void Lingo::processIf(int startlabel, int endlabel, int finalElse) {
 	}
 }
 
+int Lingo::castIdFetch(Datum &var) {
+	Score *score = _vm->getCurrentScore();
+	if (!score) {
+		warning("castFetch: Score is empty");
+		return 0;
+	}
+
+	int id = 0;
+	if (var.type == STRING) {
+		if (score->_castsNames.contains(*var.u.s))
+			id = score->_castsNames[*var.u.s];
+		else
+			warning("castFetch: reference to non-existent cast member: %s", var.u.s->c_str());
+	} else if (var.type == INT || var.type == FLOAT) {
+		var.toInt();
+		if (!score->_loadedCast->contains(var.u.i))
+			warning("castFetch: reference to non-existent cast ID: %d", var.u.i);
+		else
+			id = var.u.i;
+	} else {
+		error("castFetch: was expecting STRING or INT, got %s", var.type2str());
+	}
+
+	return id;
+}
+
 void Lingo::varAssign(Datum &var, Datum &value) {
 	if (var.type != VAR && var.type != REFERENCE) {
 		warning("varAssign: assignment to non-variable");
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 9471aabe77..f434d646ac 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -208,6 +208,7 @@ public:
 	Symbol *define(Common::String &s, int nargs, ScriptData *code);
 	Symbol *define(Common::String &s, int start, int nargs, Common::String *prefix = NULL, int end = -1, bool removeCode = true);
 	void processIf(int elselabel, int endlabel, int finalElse);
+	int castIdFetch(Datum &var);
 	void varAssign(Datum &var, Datum &value);
 	Datum varFetch(Datum &var);
 


Commit: 59d6c5e5fd0daeeb48f93034a8132949b0145ace
    https://github.com/scummvm/scummvm/commit/59d6c5e5fd0daeeb48f93034a8132949b0145ace
Author: Scott Percival (code at moral.net.au)
Date: 2020-03-21T23:40:13+08:00

Commit Message:
DIRECTOR: Fix audio lifetime, implement b_puppetSound

Changed paths:
    engines/director/archive.cpp
    engines/director/cast.cpp
    engines/director/cast.h
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/score.cpp
    engines/director/sound.cpp
    engines/director/sound.h


diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index 03f8cd6830..36b9b1ffc0 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -461,6 +461,7 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
 				 tag == MKTAG('R', 'T', 'E', '0') ||
 				 tag == MKTAG('R', 'T', 'E', '1') ||
 				 tag == MKTAG('R', 'T', 'E', '2') ||
+				 tag == MKTAG('s', 'n', 'd', ' ') ||
 				 tag == MKTAG('L', 'c', 't', 'x') ||
 				 tag == MKTAG('L', 'n', 'a', 'm') ||
 				 tag == MKTAG('L', 's', 'c', 'r'))
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index e78e5323c9..4c4cb8e4b6 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -27,6 +27,7 @@
 #include "director/cachedmactext.h"
 #include "director/cast.h"
 #include "director/score.h"
+#include "director/sound.h"
 #include "director/stxt.h"
 
 namespace Director {
diff --git a/engines/director/cast.h b/engines/director/cast.h
index caa564776b..51ae805adb 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -30,10 +30,6 @@ namespace Graphics {
 struct Surface;
 }
 
-namespace Audio {
-struct SeekableAudioStream;
-}
-
 namespace Common {
 class SeekableReadStream;
 class ReadStreamEndian;
@@ -43,6 +39,7 @@ namespace Director {
 
 class Stxt;
 class CachedMacText;
+class SNDDecoder;
 
 class Cast {
 public:
@@ -80,7 +77,7 @@ public:
 	SoundCast(Common::ReadStreamEndian &stream, uint16 version);
 
 	bool _looping;
-	Audio::SeekableAudioStream *_audio;
+	SNDDecoder *_audio;
 };
 
 class ShapeCast : public Cast {
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 75a8be1e02..c3901885bd 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -23,11 +23,13 @@
 #include "common/system.h"
 
 #include "director/director.h"
+#include "director/cast.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-builtins.h"
 #include "director/lingo/lingo-code.h"
 #include "director/frame.h"
 #include "director/score.h"
+#include "director/sound.h"
 #include "director/sprite.h"
 #include "director/stxt.h"
 
@@ -1394,11 +1396,33 @@ void LB::b_puppetPalette(int nargs) {
 }
 
 void LB::b_puppetSound(int nargs) {
-	g_lingo->convertVOIDtoString(0, nargs);
+	if (nargs != 1) {
+		error("b_puppetSound: expected 1 argument, got %d", nargs);
+		g_lingo->dropStack(nargs);
+		return;
+	}
+	Score *score = g_director->getCurrentScore();
 
-	g_lingo->printSTUBWithArglist("b_puppetSound", nargs);
+	DirectorSound *sound = g_director->getSoundManager();
+	Datum castMember = g_lingo->pop();
+	int castId = g_lingo->castIdFetch(castMember);
+
+	if (castId == 0) {
+		sound->stopSound(1);
+	} else {
+		Cast *cast = score->_loadedCast->getVal(castId);
+		if (cast->_type != kCastSound) {
+			error("b_puppetSound: attempted to play a non-SoundCast cast member");
+			return;
+		}
+		SNDDecoder *sd = ((SoundCast *)cast)->_audio;
+		if (!sd) {
+			warning("b_puppetSound: no audio data attached to cast");
+			return;
+		}
+		sound->playStream(*sd->getAudioStream(), 1);
+	}
 
-	g_lingo->dropStack(nargs);
 }
 
 void LB::b_puppetSprite(int nargs) {
@@ -1802,29 +1826,7 @@ void LB::b_cast(int nargs) {
 void LB::b_field(int nargs) {
 	Datum d = g_lingo->pop();
 
-	int id;
-
-	if (!g_director->getCurrentScore()) {
-		warning("b_field: Assigning to a field in an empty score");
-		d.u.i = 0;
-		d.type = INT;
-		g_lingo->push(d);
-		return;
-	}
-
-	if (d.type == STRING) {
-		if (g_director->getCurrentScore()->_castsNames.contains(*d.u.s))
-			id = g_director->getCurrentScore()->_castsNames[*d.u.s];
-		else
-			error("b_field: Reference to non-existent field: %s", d.u.s->c_str());
-	} else if (d.type == INT || d.type == FLOAT) {
-		d.toInt();
-		id = d.u.i;
-	} else {
-		error("b_field: Incorrect reference type: %s", d.type2str());
-	}
-
-	d.u.i = id;
+	d.u.i = g_lingo->castIdFetch(d);
 
 	d.type = REFERENCE;
 
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 36d7601474..9ba7843854 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -488,7 +488,7 @@ void Lingo::processIf(int startlabel, int endlabel, int finalElse) {
 int Lingo::castIdFetch(Datum &var) {
 	Score *score = _vm->getCurrentScore();
 	if (!score) {
-		warning("castFetch: Score is empty");
+		warning("castIdFetch: Score is empty");
 		return 0;
 	}
 
@@ -497,15 +497,15 @@ int Lingo::castIdFetch(Datum &var) {
 		if (score->_castsNames.contains(*var.u.s))
 			id = score->_castsNames[*var.u.s];
 		else
-			warning("castFetch: reference to non-existent cast member: %s", var.u.s->c_str());
+			warning("castIdFetch: reference to non-existent cast member: %s", var.u.s->c_str());
 	} else if (var.type == INT || var.type == FLOAT) {
 		var.toInt();
 		if (!score->_loadedCast->contains(var.u.i))
-			warning("castFetch: reference to non-existent cast ID: %d", var.u.i);
+			warning("castIdFetch: reference to non-existent cast ID: %d", var.u.i);
 		else
 			id = var.u.i;
 	} else {
-		error("castFetch: was expecting STRING or INT, got %s", var.type2str());
+		error("castIdFetch: was expecting STRING or INT, got %s", var.type2str());
 	}
 
 	return id;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index c714498da1..63d97ce6f5 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -698,27 +698,9 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 
 Datum Lingo::getTheCast(Datum &id1, int field) {
 	Datum d;
-	int id = 0;
-	Score *score = _vm->getCurrentScore();
-
-	if (!score) {
-		warning("Lingo::getTheCast(): The cast %d field \"%s\" setting over non-active score", id, field2str(field));
-		return d;
-	}
-
-	if (id1.type == INT) {
-		id = id1.u.i;
-	} else if (id1.type == STRING) {
-		if (score->_castsNames.contains(*id1.u.s)) {
-			id = score->_castsNames[*id1.u.s];
-		} else {
-			warning("Lingo::getTheCast(): Unknown the cast \"%s\"", id1.u.s->c_str());
-		}
-	} else {
-		warning("Lingo::getTheCast(): Unknown the cast id type: %s", id1.type2str());
-		return d;
-	}
+	int id = g_lingo->castIdFetch(id1);
 
+	Score *score = _vm->getCurrentScore();
 	// Setting default type
 	d.type = INT;
 
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index becdb55c84..58488242bd 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -403,7 +403,8 @@ void Score::loadSpriteSounds(bool isSharedCast) {
 		}
 
 		if (sndData != NULL && soundCast != NULL) {
-			Audio::SeekableAudioStream *audio = makeSNDStream(sndData);
+			SNDDecoder *audio = new SNDDecoder();
+			audio->loadStream(*sndData);
 			soundCast->_audio = audio;
 		}
 	}
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 86399ca8fb..8b18dec4aa 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -97,10 +97,14 @@ void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to)
 
 void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
 	Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(&stream);
+	playStream(*seekStream, soundChannel);
+}
+
+void DirectorSound::playStream(Audio::SeekableAudioStream &stream, uint8 soundChannel) {
 	if (soundChannel == 1)
-		_mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, seekStream);
+		_mixer->playStream(Audio::Mixer::kSFXSoundType, _sound1, &stream);
 	else
-		_mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, seekStream);
+		_mixer->playStream(Audio::Mixer::kSFXSoundType, _sound2, &stream);
 }
 
 bool DirectorSound::isChannelActive(uint8 channelID) {
@@ -115,6 +119,15 @@ bool DirectorSound::isChannelActive(uint8 channelID) {
 	return false;
 }
 
+void DirectorSound::stopSound(uint8 channelID) {
+	if (channelID == 1) {
+		_mixer->stopHandle(*_sound1);
+	} else if (channelID == 2) {
+		_mixer->stopHandle(*_sound2);
+	}
+	return;
+}
+
 void DirectorSound::stopSound() {
 	_mixer->stopHandle(*_sound1);
 	_mixer->stopHandle(*_sound2);
@@ -125,55 +138,78 @@ void DirectorSound::systemBeep() {
 	_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
 }
 
+SNDDecoder::SNDDecoder() {
+	_data = nullptr;
+	_channels = 0;
+	_size = 0;
+	_rate = 0;
+	_flags = 0;
+}
+
+SNDDecoder::~SNDDecoder() {
+	if (_data) {
+		free(_data);
+	}
+}
+
+
+bool SNDDecoder::loadStream(Common::SeekableSubReadStreamEndian &stream) {
+	if (_data) {
+		free(_data);
+		_data = nullptr;
+	}
 
-Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream) {
 	if (debugChannelSet(5, kDebugLoading)) {
 		debugC(5, kDebugLoading, "snd header:");
-		stream->hexdump(0x4e);
+		stream.hexdump(0x4e);
 	}
 
 	// unk1
 	for (uint32 i = 0; i < 0x14; i++) {
-		stream->readByte();
+		stream.readByte();
 	}
-	uint16 channels = stream->readUint16();
-	if (channels != 1 || channels != 2) {
+	_channels = stream.readUint16();
+	if (!(_channels == 1 || _channels == 2)) {
 		warning("STUB: loadSpriteSounds: no support for old sound format");
-		return NULL;
+		return false;
 	}
-	uint16 rate = stream->readUint16();
+	_rate = stream.readUint16();
 
 	// unk2
 	for (uint32 i = 0; i < 0x06; i++) {
-		stream->readByte();
+		stream.readByte();
 	}
-	uint32 length = stream->readUint32();
-	/*uint16 unk3 =*/stream->readUint16();
-	/*uint32 length_copy =*/stream->readUint32();
-	/*uint8 unk4 =*/stream->readByte();
-	/*uint8 unk5 =*/stream->readByte();
-	/*uint16 unk6 =*/stream->readUint16();
+	uint32 length = stream.readUint32();
+	/*uint16 unk3 =*/stream.readUint16();
+	/*uint32 length_copy =*/stream.readUint32();
+	/*uint8 unk4 =*/stream.readByte();
+	/*uint8 unk5 =*/stream.readByte();
+	/*uint16 unk6 =*/stream.readUint16();
 	// unk7
 	for (uint32 i = 0; i < 0x12; i++) {
-		stream->readByte();
+		stream.readByte();
 	}
-	uint16 bits = stream->readUint16();
+	uint16 bits = stream.readUint16();
 	// unk8
 	for (uint32 i = 0; i < 0x0c; i++) {
-		stream->readByte();
+		stream.readByte();
 	}
 
-	byte flags = 0;
-	flags |= channels == 2 ? Audio::FLAG_STEREO : 0;
-	flags |= bits == 16 ? Audio::FLAG_16BITS : 0;
-	flags |= bits == 8 ? Audio::FLAG_UNSIGNED : 0;
-	uint32 size = length * channels * (bits == 16 ? 2 : 1);
+	_flags = 0;
+	_flags |= _channels == 2 ? Audio::FLAG_STEREO : 0;
+	_flags |= bits == 16 ? Audio::FLAG_16BITS : 0;
+	_flags |= bits == 8 ? Audio::FLAG_UNSIGNED : 0;
+	_size = length * _channels * (bits == 16 ? 2 : 1);
 
-	byte *data = (byte *)malloc(size);
-	assert(data);
-	stream->read(data, size);
+	_data = (byte *)malloc(_size);
+	assert(_data);
+	stream.read(_data, _size);
+
+	return true;
+}
 
-	return Audio::makeRawStream(data, size, rate, flags);
+Audio::SeekableAudioStream *SNDDecoder::getAudioStream() {
+	return Audio::makeRawStream(_data, _size, _rate, _flags, DisposeAfterUse::NO);
 }
 
 
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 2942ddd4a1..38677a4a53 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -50,12 +50,29 @@ public:
 	void playAIFF(Common::String filename, uint8 channelID);
 	void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
 	void playStream(Audio::AudioStream &stream, uint8 soundChannel);
+	void playStream(Audio::SeekableAudioStream &stream, uint8 soundChannel);
 	void systemBeep();
 	bool isChannelActive(uint8 channelID);
+	void stopSound(uint8 channelID);
 	void stopSound();
 };
 
-Audio::SeekableAudioStream *makeSNDStream(Common::SeekableSubReadStreamEndian *stream);
+
+class SNDDecoder {
+public:
+	SNDDecoder();
+	~SNDDecoder();
+
+	bool loadStream(Common::SeekableSubReadStreamEndian &stream);
+	Audio::SeekableAudioStream *getAudioStream();
+
+private:
+	byte *_data;
+	uint16 _channels;
+	uint32 _size;
+	uint16 _rate;
+	byte _flags;
+};
 
 } // End of namespace Director
 




More information about the Scummvm-git-logs mailing list