[Scummvm-cvs-logs] scummvm master -> b680af7f609594a89dd9acd8227c7d19259f8e6d

dreammaster dreammaster at scummvm.org
Fri Aug 12 02:04:04 CEST 2016


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

Summary:
b680af7f60 TITANIC: Fleshing out QSound simulation methods


Commit: b680af7f609594a89dd9acd8227c7d19259f8e6d
    https://github.com/scummvm/scummvm/commit/b680af7f609594a89dd9acd8227c7d19259f8e6d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2016-08-11T20:03:55-04:00

Commit Message:
TITANIC: Fleshing out QSound simulation methods

Changed paths:
    engines/titanic/sound/qmixer.cpp
    engines/titanic/sound/qmixer.h
    engines/titanic/sound/sound_manager.cpp
    engines/titanic/sound/wave_file.cpp
    engines/titanic/sound/wave_file.h



diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp
index da707c9..da4f672 100644
--- a/engines/titanic/sound/qmixer.cpp
+++ b/engines/titanic/sound/qmixer.cpp
@@ -28,7 +28,10 @@ QMixer::QMixer(Audio::Mixer *mixer) : _mixer(mixer) {
 }
 
 bool QMixer::qsWaveMixInitEx(const QMIXCONFIG &config) {
-	// Not currently implemented in ScummVM
+	assert(_channels.empty());
+	assert(config.iChannels > 0 && config.iChannels < 256);
+	
+	_channels.resize(config.iChannels);
 	return true;
 }
 
@@ -48,6 +51,7 @@ int QMixer::qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled) {
 
 void QMixer::qsWaveMixCloseSession() {
 	_mixer->stopAll();
+	_channels.clear();
 }
 
 void QMixer::qsWaveMixFreeWave(Audio::SoundHandle &handle) {
@@ -94,18 +98,62 @@ void QMixer::qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR
 	// Not currently implemented in ScummVM
 }
 
-int QMixer::qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *mixWave, int loops, const QMIXPLAYPARAMS &params) {
-	// Not currently implemented in ScummVM
+int QMixer::qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS &params) {
+	if (iChannel == -1) {
+		// Find a free channel
+		for (iChannel = 0; iChannel < (int)_channels.size(); ++iChannel) {
+			if (_channels[iChannel]._sounds.empty())
+				break;
+		}
+		assert(iChannel != (int)_channels.size());
+	}
+
+	// If the new sound replaces current ones, then clear the channel
+	ChannelEntry &channel = _channels[iChannel];
+	if (flags & QMIX_CLEARQUEUE) {
+		if (!channel._sounds.empty() && channel._sounds.front()._started)
+			_mixer->stopHandle(channel._sounds.front()._soundHandle);
+
+		channel._sounds.clear();
+	}
+
+	// Add the sound to the channel
+	channel._sounds.push_back(SoundEntry(waveFile, params.callback, params.dwUser));
+	qsWaveMixPump();
+
 	return 0;
 }
 
 bool QMixer::qsWaveMixIsChannelDone(int iChannel) const {
-	// Not currently implemented in ScummVM
-	return true;
+	return _channels[iChannel]._sounds.empty();
 }
 
 void QMixer::qsWaveMixPump() {
-	// TODO: Handle checking for done sounds, and calling their end functions
+	// Iterate through each of the channels
+	for (uint iChannel = 0; iChannel < _channels.size(); ++iChannel) {
+		ChannelEntry &channel = _channels[iChannel];
+
+		// If the playing sound on the channel is finished, then call
+		// the callback registered for it, and remove it from the list
+		if (!channel._sounds.empty()) {
+			SoundEntry &sound = channel._sounds.front();
+			if (sound._started && !_mixer->isSoundHandleActive(sound._soundHandle)) {
+				sound._callback(iChannel, sound._waveFile, sound._userData);
+				channel._sounds.erase(channel._sounds.begin());
+			}
+		}
+
+		// If there's an unstarted sound at the front of a channel's
+		// sound list, then start it playing
+		if (!channel._sounds.empty()) {
+			SoundEntry &sound = channel._sounds.front();
+			if (!sound._started) {
+				_mixer->playStream(sound._waveFile->_soundType,
+					&sound._soundHandle, sound._waveFile->_stream);
+				sound._started = true;
+			}
+		}
+	}
 }
 
 } // End of namespace Titanic z
diff --git a/engines/titanic/sound/qmixer.h b/engines/titanic/sound/qmixer.h
index fa4604c..32a5e58 100644
--- a/engines/titanic/sound/qmixer.h
+++ b/engines/titanic/sound/qmixer.h
@@ -152,9 +152,12 @@ struct QMIXPLAYPARAMS {
 	int lEndLoop;
 	int lEnd;
 	const void *lpChannelParams;	// initialize with these parameters
+	// Properties introduced by ScummVM
+	Audio::Mixer::SoundType _soundType;
 
 	QMIXPLAYPARAMS() : dwSize(36), lpImage(nullptr), hwndNotify(0), callback(nullptr),
-		dwUser(nullptr), lStart(0), lStartLoop(0), lEndLoop(0), lEnd(0), lpChannelParams(nullptr) {}
+		dwUser(nullptr), lStart(0), lStartLoop(0), lEndLoop(0), lEnd(0), 
+		lpChannelParams(nullptr), _soundType(Audio::Mixer::SoundType::kPlainSoundType)  {}
 };
 
 /**
@@ -169,8 +172,24 @@ struct QMIXPLAYPARAMS {
  * currently ignored, and all sounds play at full volume.
  */
 class QMixer {
+	struct SoundEntry {
+		bool _started;
+		CWaveFile *_waveFile;
+		Audio::SoundHandle _soundHandle;
+		LPQMIXDONECALLBACK _callback;
+		void *_userData;
+		SoundEntry() : _started(false), _waveFile(nullptr), _callback(nullptr),
+			_userData(nullptr) {}
+
+		SoundEntry(CWaveFile *waveFile, LPQMIXDONECALLBACK callback, void *userData) :
+			_started(false), _waveFile(waveFile), _callback(callback), _userData(userData) {}
+	};
+	struct ChannelEntry {
+		Common::List<SoundEntry> _sounds;
+	};
 private:
 	Audio::Mixer *_mixer;
+	Common::Array<ChannelEntry> _channels;
 public:
 	QMixer(Audio::Mixer *mixer);
 	virtual ~QMixer() {}
diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp
index d466488..8d92e0c 100644
--- a/engines/titanic/sound/sound_manager.cpp
+++ b/engines/titanic/sound/sound_manager.cpp
@@ -143,7 +143,15 @@ CWaveFile *QSoundManager::loadSpeech(CDialogueFile *dialogueFile, int speechId)
 }
 
 CWaveFile *QSoundManager::loadMusic(const CString &name) {
-	return loadSound(name);
+	CWaveFile *waveFile = new CWaveFile();
+
+	// Try to load the specified sound
+	if (!waveFile->loadMusic(name)) {
+		delete waveFile;
+		return nullptr;
+	}
+
+	return waveFile;
 }
 
 int QSoundManager::playSound(CWaveFile &waveFile, CProximity &prox) {
diff --git a/engines/titanic/sound/wave_file.cpp b/engines/titanic/sound/wave_file.cpp
index 7093856..16bc9de 100644
--- a/engines/titanic/sound/wave_file.cpp
+++ b/engines/titanic/sound/wave_file.cpp
@@ -28,11 +28,12 @@
 
 namespace Titanic {
 
-CWaveFile::CWaveFile() : _owner(nullptr), _stream(nullptr), _soundType(SOUND_SFX) {
+CWaveFile::CWaveFile() : _owner(nullptr), _stream(nullptr),
+		_soundType(Audio::Mixer::SoundType::kPlainSoundType) {
 }
 
 CWaveFile::CWaveFile(QSoundManager *owner) : _owner(owner), _stream(nullptr),
-		_soundType(SOUND_SFX) {
+		_soundType(Audio::Mixer::SoundType::kPlainSoundType) {
 }
 
 CWaveFile::~CWaveFile() {
@@ -57,7 +58,8 @@ bool CWaveFile::loadSound(const CString &name) {
 	Common::SeekableReadStream *stream = file.readStream();
 	_size = stream->size();
 	_stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES);
-	_soundType = SOUND_SFX;
+	_soundType = Audio::Mixer::SoundType::kSFXSoundType;
+
 	return true;
 }
 
@@ -72,7 +74,23 @@ bool CWaveFile::loadSpeech(CDialogueFile *dialogueFile, int speechIndex) {
 	_size = res->_size;
 	_stream = Audio::makeWAVStream(new Common::MemoryReadStream(data, _size, DisposeAfterUse::YES),
 		DisposeAfterUse::YES);
-	_soundType = SOUND_SPEECH;
+	_soundType = Audio::Mixer::SoundType::kSpeechSoundType;
+
+	return true;
+}
+
+bool CWaveFile::loadMusic(const CString &name) {
+	assert(!_stream);
+
+	StdCWadFile file;
+	if (!file.open(name))
+		return false;
+
+	Common::SeekableReadStream *stream = file.readStream();
+	_size = stream->size();
+	_stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES);
+	_soundType = Audio::Mixer::SoundType::kMusicSoundType;
+
 	return true;
 }
 
diff --git a/engines/titanic/sound/wave_file.h b/engines/titanic/sound/wave_file.h
index 33b2a8d..8c86c50 100644
--- a/engines/titanic/sound/wave_file.h
+++ b/engines/titanic/sound/wave_file.h
@@ -32,11 +32,6 @@ namespace Titanic {
 
 class QSoundManager;
 
-enum SoundType {
-	SOUND_SFX = 0,
-	SOUND_SPEECH = 1
-};
-
 class CWaveFile {
 private:
 	uint _size;
@@ -44,7 +39,7 @@ public:
 	QSoundManager *_owner;
 	Audio::AudioStream *_stream;
 	Audio::SoundHandle _soundHandle;
-	SoundType _soundType;
+	Audio::Mixer::SoundType _soundType;
 public:
 	CWaveFile();
 	CWaveFile(QSoundManager *owner);
@@ -68,6 +63,11 @@ public:
 	bool loadSpeech(CDialogueFile *dialogueFile, int speechIndex);
 
 	/**
+	 * Tries to load the specified music wave file
+	 */
+	bool loadMusic(const CString &name);
+
+	/**
 	 * Returns true if the wave file has data loaded
 	 */
 	bool isLoaded() const { return _stream != nullptr; }






More information about the Scummvm-git-logs mailing list