[Scummvm-git-logs] scummvm master -> 2729e141cce358fd6f509a4e44b2738eb22146e8

moralrecordings code at moral.net.au
Sun Jun 21 09:28:02 UTC 2020


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

Summary:
6a6cf9d86e DIRECTOR: Load properties from digital video cast
2729e141cc DIRECTOR: Add support for linked sound cast members


Commit: 6a6cf9d86ebb0bd2e23263d7ec7ca297cf41b239
    https://github.com/scummvm/scummvm/commit/6a6cf9d86ebb0bd2e23263d7ec7ca297cf41b239
Author: Scott Percival (code at moral.net.au)
Date: 2020-06-21T17:27:37+08:00

Commit Message:
DIRECTOR: Load properties from digital video cast

Changed paths:
    engines/director/cast.cpp
    engines/director/cast.h
    engines/director/score-loading.cpp
    engines/director/types.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 124c84e25e..45a73bc96f 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -146,6 +146,32 @@ void BitmapCast::createWidget() {
 	_widget->getSurface()->blitFrom(*_img->getSurface());
 }
 
+DigitalVideoCast::DigitalVideoCast(Common::ReadStreamEndian &stream, uint16 version) {
+	_type = kCastDigitalVideo;
+
+	for (int i = 0; i < 4; i++) {
+		stream.readUint16();
+	}
+	_frameRate = stream.readByte();
+	stream.readByte();
+
+	byte flags1 = stream.readByte();
+	_frameRateType = kFrameRateDefault;
+	if (flags1 & 0x08) {
+		_frameRateType = (FrameRateType)((flags1 & 0x30) >> 4);
+	}
+	_preload = flags1 & 0x04;
+	_enableVideo = ~(flags1 & 0x02);
+	_pauseAtStart = flags1 & 0x01;
+
+	byte flags2 = stream.readByte();
+	_showControls = flags2 & 0x40;
+	_looping = flags2 & 0x10;
+	_enableSound = flags2 & 0x08;
+	_enableCrop = ~(flags2 & 0x02);
+	_center = flags2 & 0x01;
+}
+
 SoundCast::SoundCast(Common::ReadStreamEndian &stream, uint16 version) {
 	_type = kCastSound;
 	_audio = nullptr;
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 8d97cb9e2b..cf93abcab4 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -95,6 +95,23 @@ public:
 	uint32 _tag;
 };
 
+class DigitalVideoCast : public Cast {
+public:
+	DigitalVideoCast(Common::ReadStreamEndian &stream, uint16 version);
+
+	bool _looping;
+	bool _pauseAtStart;
+	bool _enableVideo;
+	bool _enableSound;
+	bool _enableCrop;
+	bool _center;
+	bool _preload;
+	bool _showControls;
+	FrameRateType _frameRateType;
+
+	uint16 _frameRate;
+};
+
 class SoundCast : public Cast {
 public:
 	SoundCast(Common::ReadStreamEndian &stream, uint16 version);
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index 21422b199a..517f27ef2d 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -671,6 +671,10 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
 			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) SoundCast", id, numToCastNum(id));
 			_loadedCast->setVal(id, new SoundCast(stream, _vm->getVersion()));
 			break;
+		case kCastDigitalVideo:
+			debugC(3, kDebugLoading, "Score::loadCastDataVWCR(): CastTypes id: %d(%s) DigitalVideoCast", id, numToCastNum(id));
+			_loadedCast->setVal(id, new DigitalVideoCast(stream, _vm->getVersion()));
+			break;
 		default:
 			warning("Score::loadCastDataVWCR(): Unhandled cast id: %d(%s), type: %d, %d bytes", id, numToCastNum(id), castType, size);
 			stream.skip(size - 1);
@@ -784,6 +788,10 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastRTE (%d children)", res->children.size());
 		_loadedCast->setVal(id, new RTECast(castStream, _vm->getVersion()));
 		break;
+	case kCastDigitalVideo:
+		debugC(3, kDebugLoading, "Score::loadCastData(): loading kCastDigitalVideo (%d children)", res->children.size());
+		_loadedCast->setVal(id, new DigitalVideoCast(castStream, _vm->getVersion()));
+		break;
 	case kCastFilmLoop:
 		warning("STUB: Score::loadCastData(): kCastFilmLoop (%d children)", res->children.size());
 		size2 = 0;
@@ -800,10 +808,6 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		warning("STUB: Score::loadCastData(): kCastMovie (%d children)", res->children.size());
 		size2 = 0;
 		break;
-	case kCastDigitalVideo:
-		warning("STUB: Score::loadCastData(): kCastDigitalVideo (%d children)", res->children.size());
-		size2 = 0;
-		break;
 	default:
 		warning("Score::loadCastData(): Unhandled cast type: %d [%s] (%d children)", castType, tag2str(castType), res->children.size());
 		// also don't try and read the strings... we don't know what this item is.
diff --git a/engines/director/types.h b/engines/director/types.h
index 5b332fd6d0..d9f999e6be 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -90,6 +90,13 @@ enum ButtonType {
 	kTypeRadio
 };
 
+enum FrameRateType {
+	kFrameRateDefault = -1,
+	kFrameRateNormal = 0,
+	kFrameRateFastest = 1,
+	kFrameRateFixed = 2
+};
+
 enum SpriteType {
 	kInactiveSprite					= 0,	// turns the sprite off
 	kBitmapSprite					= 1,


Commit: 2729e141cce358fd6f509a4e44b2738eb22146e8
    https://github.com/scummvm/scummvm/commit/2729e141cce358fd6f509a4e44b2738eb22146e8
Author: Scott Percival (code at moral.net.au)
Date: 2020-06-21T17:27:37+08:00

Commit Message:
DIRECTOR: Add support for linked sound cast members

Changed paths:
    engines/director/cast.h
    engines/director/lingo/lingo-the.cpp
    engines/director/score-loading.cpp
    engines/director/sound.cpp
    engines/director/sound.h


diff --git a/engines/director/cast.h b/engines/director/cast.h
index cf93abcab4..2b9a0120e4 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -48,7 +48,7 @@ class ImageDecoder;
 namespace Director {
 
 class Stxt;
-class SNDDecoder;
+class AudioDecoder;
 
 class Cast {
 public:
@@ -117,7 +117,7 @@ public:
 	SoundCast(Common::ReadStreamEndian &stream, uint16 version);
 
 	bool _looping;
-	SNDDecoder *_audio;
+	AudioDecoder *_audio;
 };
 
 class ShapeCast : public Cast {
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index db1115d8db..e4c8462c89 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -505,6 +505,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		else
 			d.u.s = new Common::String();
 		break;
+	case kTheMultiSound:
+		// We always support multiple sound channels!
+		d.type = INT;
+		d.u.i = 1;
+		break;
 	case kThePerFrameHook:
 		d = _perFrameHook;
 		break;
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index 517f27ef2d..4bc17a3531 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -409,10 +409,16 @@ void Score::loadSpriteSounds(bool isSharedCast) {
 		}
 
 		if (sndData != NULL && soundCast != NULL) {
-			SNDDecoder *audio = new SNDDecoder();
-			audio->loadStream(*sndData);
+			if (sndData->size() == 0) {
+				// audio file is linked, load from the filesystem
+				AudioFileDecoder *audio = new AudioFileDecoder(_castsInfo[c->_key]->fileName);
+				soundCast->_audio = audio;
+			} else {
+				SNDDecoder *audio = new SNDDecoder();
+				audio->loadStream(*sndData);
+				soundCast->_audio = audio;
+			}
 			delete sndData;
-			soundCast->_audio = audio;
 		}
 	}
 }
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 241786ea11..5e2c6b3e34 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -74,74 +74,9 @@ void DirectorSound::playFile(Common::String filename, uint8 soundChannel) {
 	if (debugChannelSet(-1, kDebugFast))
 		return;
 
-	Common::File *file = new Common::File();
-
-	if (!file->open(filename)) {
-		warning("Failed to open %s", filename.c_str());
-
-		delete file;
-
-		return;
-	}
-
-	uint32 magic1 = file->readUint32BE();
-	file->readUint32BE();
-	uint32 magic2 = file->readUint32BE();
-	delete file;
-
-	if (magic1 == MKTAG('R', 'I', 'F', 'F') &&
-		magic2 == MKTAG('W', 'A', 'V', 'E')) {
-		playWAV(filename, soundChannel);
-	} else if (magic1 == MKTAG('F', 'O', 'R', 'M') &&
-				magic2 == MKTAG('A', 'I', 'F', 'F')) {
-		playAIFF(filename, soundChannel);
-	} else {
-		warning("Unknown file type for %s", filename.c_str());
-	}
-}
-
-void DirectorSound::playWAV(Common::String filename, uint8 soundChannel) {
-	if (soundChannel == 0 || soundChannel > _channels.size()) {
-		warning("Invalid sound channel %d", soundChannel);
-
-		return;
-	}
-	_channels[soundChannel - 1].lastPlayingCast = 0;
-
-	Common::File *file = new Common::File();
-
-	if (!file->open(filename)) {
-		warning("Failed to open %s", filename.c_str());
-
-		delete file;
-
-		return;
-	}
-
-	Audio::RewindableAudioStream *sound = Audio::makeWAVStream(file, DisposeAfterUse::YES);
-
-	_mixer->stopHandle(_channels[soundChannel - 1].handle);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, sound, -1, _channels[soundChannel - 1].volume);
-}
-
-void DirectorSound::playAIFF(Common::String filename, uint8 soundChannel) {
-	if (soundChannel == 0 || soundChannel > _channels.size()) {
-		warning("Invalid sound channel %d", soundChannel);
-		return;
-	}
-	_channels[soundChannel - 1].lastPlayingCast = 0;
+	AudioFileDecoder af(filename);
+	Audio::RewindableAudioStream *sound = af.getAudioStream(DisposeAfterUse::YES);
 
-	Common::File *file = new Common::File();
-
-	if (!file->open(filename)) {
-		warning("Failed to open %s", filename.c_str());
-		delete file;
-		return;
-	}
-
-	Audio::RewindableAudioStream *sound = Audio::makeAIFFStream(file, DisposeAfterUse::YES);
-
-	_mixer->stopHandle(_channels[soundChannel - 1].handle);
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, sound, -1, _channels[soundChannel - 1].volume);
 }
 
@@ -175,16 +110,16 @@ void DirectorSound::playCastMember(int castId, uint8 soundChannel, bool allowRep
 				if (!allowRepeat && lastPlayingCast(soundChannel) == castId)
 					return;
 				bool looping = ((SoundCast *)soundCast)->_looping;
-				SNDDecoder *sd = ((SoundCast *)soundCast)->_audio;
-				if (!sd) {
+				AudioDecoder *ad = ((SoundCast *)soundCast)->_audio;
+				if (!ad) {
 					warning("DirectorSound::playCastMember: no audio data attached to cast member %d", castId);
 					return;
 				}
 				Audio::AudioStream *as;
 				if (looping)
-					as = sd->getLoopingAudioStream();
+					as = ad->getLoopingAudioStream();
 				else
-					as = sd->getAudioStream();
+					as = ad->getAudioStream();
 				if (!as) {
 					warning("DirectorSound::playCastMember: audio data failed to load from cast");
 					return;
@@ -240,6 +175,13 @@ void DirectorSound::systemBeep() {
 	_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
 }
 
+Audio::AudioStream *AudioDecoder::getLoopingAudioStream() {
+	Audio::RewindableAudioStream *target = getAudioStream(DisposeAfterUse::NO);
+	if (!target)
+		return nullptr;
+	return new Audio::LoopingAudioStream(target, 0);
+}
+
 SNDDecoder::SNDDecoder() {
 	_data = nullptr;
 	_channels = 0;
@@ -380,16 +322,38 @@ bool SNDDecoder::processBufferCommand(Common::SeekableSubReadStreamEndian &strea
 	return true;
 }
 
-Audio::SeekableAudioStream *SNDDecoder::getAudioStream() {
+Audio::RewindableAudioStream *SNDDecoder::getAudioStream(DisposeAfterUse::Flag disposeAfterUse) {
 	if (!_data)
 		return nullptr;
-	return Audio::makeRawStream(_data, _size, _rate, _flags, DisposeAfterUse::NO);
+	byte *buffer = (byte *)malloc(_size);
+	memcpy(buffer, _data, _size);
+	return Audio::makeRawStream(buffer, _size, _rate, _flags, disposeAfterUse);
 }
 
-Audio::AudioStream *SNDDecoder::getLoopingAudioStream() {
-	if (!_data)
+Audio::RewindableAudioStream *AudioFileDecoder::getAudioStream(DisposeAfterUse::Flag disposeAfterUse) {
+	if (_path.empty())
 		return nullptr;
-	return new Audio::LoopingAudioStream(Audio::makeRawStream(_data, _size, _rate, _flags, DisposeAfterUse::NO), 0);
+
+	Common::File *file = new Common::File();
+	if (!file->open(_path)) {
+		warning("Failed to open %s", _path.c_str());
+		return nullptr;
+	}
+	uint32 magic1 = file->readUint32BE();
+	file->readUint32BE();
+	uint32 magic2 = file->readUint32BE();
+	file->seek(0);
+	if (magic1 == MKTAG('R', 'I', 'F', 'F') &&
+		magic2 == MKTAG('W', 'A', 'V', 'E')) {
+		return Audio::makeWAVStream(file, disposeAfterUse);
+	} else if (magic1 == MKTAG('F', 'O', 'R', 'M') &&
+				magic2 == MKTAG('A', 'I', 'F', 'F')) {
+		return Audio::makeAIFFStream(file, disposeAfterUse);
+	} else {
+		warning("Unknown file type for %s", _path.c_str());
+	}
+
+	return nullptr;
 }
 
 
diff --git a/engines/director/sound.h b/engines/director/sound.h
index b45c588b94..75fe3fb882 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -29,7 +29,7 @@ namespace Audio {
 	class AudioStream;
 	class SoundHandle;
 	class PCSpeaker;
-	class SeekableAudioStream;
+	class RewindableAudioStream;
 }
 
 namespace Director {
@@ -57,8 +57,6 @@ public:
 	~DirectorSound();
 
 	SoundChannel *getChannel(uint8 soundChannel);
-	void playWAV(Common::String filename, uint8 soundChannel);
-	void playAIFF(Common::String filename, uint8 soundChannel);
 	void playFile(Common::String filename, uint8 soundChannel);
 	void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
 	void playStream(Audio::AudioStream &stream, uint8 soundChannel);
@@ -70,8 +68,15 @@ public:
 	void stopSound();
 };
 
+class AudioDecoder {
+public:
+	virtual ~AudioDecoder() {};
+public:
+	virtual Audio::RewindableAudioStream *getAudioStream(DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) = 0;
+	virtual Audio::AudioStream *getLoopingAudioStream();
+};
 
-class SNDDecoder {
+class SNDDecoder : public AudioDecoder {
 public:
 	SNDDecoder();
 	~SNDDecoder();
@@ -79,8 +84,7 @@ public:
 	bool loadStream(Common::SeekableSubReadStreamEndian &stream);
 	bool processCommands(Common::SeekableSubReadStreamEndian &stream);
 	bool processBufferCommand(Common::SeekableSubReadStreamEndian &stream);
-	Audio::SeekableAudioStream *getAudioStream();
-	Audio::AudioStream *getLoopingAudioStream();
+	Audio::RewindableAudioStream *getAudioStream(DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
 
 private:
 	byte *_data;
@@ -90,6 +94,19 @@ private:
 	byte _flags;
 };
 
+class AudioFileDecoder: public AudioDecoder {
+public:
+	AudioFileDecoder(Common::String &path): _path(path) {};
+	~AudioFileDecoder() {};
+
+	void setPath(Common::String &path);
+
+	Audio::RewindableAudioStream *getAudioStream(DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
+
+private:
+	Common::String _path;
+};
+
 } // End of namespace Director
 
 #endif




More information about the Scummvm-git-logs mailing list