diff options
| -rw-r--r-- | engines/kyra/lol.cpp | 262 | ||||
| -rw-r--r-- | engines/kyra/lol.h | 3 | ||||
| -rw-r--r-- | engines/kyra/module.mk | 1 | ||||
| -rw-r--r-- | engines/kyra/script_lol.cpp | 4 | ||||
| -rw-r--r-- | engines/kyra/script_tim.cpp | 8 | ||||
| -rw-r--r-- | engines/kyra/sound.cpp | 85 | ||||
| -rw-r--r-- | engines/kyra/sound.h | 16 | ||||
| -rw-r--r-- | engines/kyra/sound_lol.cpp | 317 | ||||
| -rw-r--r-- | engines/kyra/sound_towns.cpp | 2 | ||||
| -rw-r--r-- | engines/kyra/text_lol.cpp | 2 | 
10 files changed, 369 insertions, 331 deletions
| diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index da0703f5e0..02f3020ec0 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -412,6 +412,10 @@ LoLEngine::~LoLEngine() {  	for (Common::Array<const SpellProc*>::iterator i = _spellProcs.begin(); i != _spellProcs.end(); ++i)  		delete *i;  	_spellProcs.clear(); + +	for (Common::List<Audio::AudioStream *>::iterator i = _speechList.begin(); i != _speechList.end(); ++i) +		delete *i; +	_speechList.clear();  }  Screen *LoLEngine::screen() { @@ -896,7 +900,7 @@ void LoLEngine::update() {  	if (_gameFlags[15] & 0x4000 && !(_updateFlags & 4) && (_compassDirection == -1 || (_currentDirection << 6) != _compassDirection || _compassStep))  		updateCompass(); -	snd_characterSpeaking(); +	snd_updateCharacterSpeech();  	fadeText();  	updateInput(); @@ -1096,7 +1100,7 @@ void LoLEngine::updatePortraitSpeechAnim() {  	f += 7;  	if (_speechFlag) { -		if (snd_characterSpeaking() == 2) +		if (snd_updateCharacterSpeech() == 2)  			_updatePortraitSpeechAnimDuration = 2;  		else  			_updatePortraitSpeechAnimDuration = 1; @@ -1670,260 +1674,6 @@ void LoLEngine::loadTalkFile(int index) {  	_res->loadPakFile(file);  } -bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) { -	if (!_speechFlag) -		return false; - -	if (speaker < 65) { -		if (_characters[speaker].flags & 1) -			speaker = (int) _characters[speaker].name[0]; -		else -			speaker = 0; -	} - -	if (_lastSpeechId == id && speaker == _lastSpeaker) -		return true; - -	_lastSpeechId = id; -	_lastSpeaker = speaker; -	_nextSpeechId = _nextSpeaker = -1; - -	Common::List<const char*> playList; - -	char pattern1[8]; -	char pattern2[5]; -	char file1[13]; -	char file2[13]; -	char file3[13]; -	file3[0] = 0; - -	snprintf(pattern2, sizeof(pattern2), "%02d", id & 0x4000 ? 0 : _curTlkFile); - -	if (id & 0x4000) { -		snprintf(pattern1, sizeof(pattern1), "%03X", id & 0x3fff); -	} else if (id < 1000) { -		snprintf(pattern1, sizeof(pattern1), "%03d", id); -	} else { -		snprintf(file3, sizeof(file3), "@%04d%c.%s", id - 1000, (char)speaker, pattern2); -		if (_res->exists(file3)) { -			char *f = new char[strlen(file3) + 1]; -			strcpy(f, file3); -			playList.push_back(f); -		} -	} - -	if (!file3[0]) { -		for (char i = 0; ; i++) { -			char symbol = '0' + i; -			snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, symbol, pattern2); -			snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', symbol, pattern2); -			if (_res->exists(file1)) { -				char *f = new char[strlen(file1) + 1]; -				strcpy(f, file1); -				playList.push_back(f); -			} else if (_res->exists(file2)) { -				char *f = new char[strlen(file2) + 1]; -				strcpy(f, file2); -				playList.push_back(f); -			} else { -				break; -			} -		} -	} - -	if (playList.empty()) -		return false; - -	while (_sound->voiceIsPlaying(_activeVoiceFile)) -		delay(_tickLength, true, false); - -	while (_sound->allVoiceChannelsPlaying()) -		delay(_tickLength, false, true); - -	strcpy(_activeVoiceFile, *playList.begin()); -	_activeVoiceFileTotalTime = _sound->voicePlayFromList(playList); - -	for (Common::List<const char*>::iterator i = playList.begin(); i != playList.end(); i++) -		delete []*i; -	playList.clear(); - -	_tim->_abortFlag = 0; - -	return true; -} - -int LoLEngine::snd_characterSpeaking() { -	if (_sound->voiceIsPlaying(_activeVoiceFile)) -		return 2; - -	_lastSpeechId = _lastSpeaker = -1; -	_activeVoiceFileTotalTime = 0; - -	if (_nextSpeechId != -1) { -		if (snd_playCharacterSpeech(_nextSpeechId, _nextSpeaker, 0)) -			return 2; -	} - -	return 0; -} - -void LoLEngine::snd_stopSpeech(bool setFlag) { -	if (!_sound->voiceIsPlaying(_activeVoiceFile)) -		return; - -	//_dlgTimer = 0; -	_sound->voiceStop(_activeVoiceFile); -	_activeVoiceFileTotalTime = 0; -	_nextSpeechId = _nextSpeaker = -1; - -	if (setFlag) -		_tim->_abortFlag = 1; -} - -void LoLEngine::snd_playSoundEffect(int track, int volume) { -	if (track == 1 && (_lastSfxTrack == -1 || _lastSfxTrack == 1)) -		return; - -	_lastSfxTrack = track; -	if (track == -1) -		return; - -	int16 volIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2 + 1]); - -	if (volIndex > 0) -		volume = (volIndex * volume) >> 8; -	else if (volIndex < 0) -		volume = -volIndex; - -	// volume TODO -	volume = 254 - volume; - -	int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]); - -	bool hasVocFile = false; -	if (vocIndex != -1) { -		if (scumm_stricmp(_ingameSoundList[vocIndex], "EMPTY")) -			hasVocFile = true; -	} - -	if (hasVocFile) { -		_sound->voicePlay(_ingameSoundList[vocIndex], volume & 0xff, true); -	} else if (_flags.platform == Common::kPlatformPC) { -		if (_sound->getSfxType() == Sound::kMidiMT32) -			track = track < _ingameMT32SoundIndexSize ? _ingameMT32SoundIndex[track] - 1 : -1; -		else if (_sound->getSfxType() == Sound::kMidiGM) -			track = track < _ingameGMSoundIndexSize ? _ingameGMSoundIndex[track] - 1: -1; - -		if (track == 168) -			track = 167; - -		if (track != -1) -			KyraEngine_v1::snd_playSoundEffect(track, volume); -	} -} - -void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { -	if (!_sound->sfxEnabled()) -		return; - -	if (_environmentSfx) -		snd_playSoundEffect(_environmentSfx, _environmentSfxVol); - -	int dist = 0; -	if (block) { -		dist = getMonsterDistance(_currentBlock, block); -		if (dist > _envSfxDistThreshold) { -			_environmentSfx = 0; -			return; -		} -	} - -	_environmentSfx = soundId; -	_environmentSfxVol = (15 - ((block || dist < 2) ? dist : 0)) << 4; - -	if (block != _currentBlock) { -		static const int8 blockShiftTable[] = { -32, -31, 1, 33, 32, 31, -1, -33 }; -		uint16 cbl = _currentBlock; - -		for (int i = 3; i > 0; i--) { -			int dir = calcMonsterDirection(cbl & 0x1f, cbl >> 5, block & 0x1f, block >> 5); -			cbl += blockShiftTable[dir]; -			if (cbl != block) { -				if (testWallFlag(cbl, 0, 1)) -					_environmentSfxVol >>= 1; -			} -		} -	} - -	if (!soundId || _sceneUpdateRequired) -		return; - -	snd_processEnvironmentalSoundEffect(0, 0); -} - -void LoLEngine::snd_queueEnvironmentalSoundEffect(int soundId, int block) { -	if (_envSfxUseQueue && _envSfxNumTracksInQueue < 10) { -		_envSfxQueuedTracks[_envSfxNumTracksInQueue] = soundId; -		_envSfxQueuedBlocks[_envSfxNumTracksInQueue] = block; -		_envSfxNumTracksInQueue++; -	} else { -		snd_processEnvironmentalSoundEffect(soundId, block); -	} -} - -void LoLEngine::snd_playQueuedEffects() { -	for (int i = 0; i < _envSfxNumTracksInQueue; i++) -		snd_processEnvironmentalSoundEffect(_envSfxQueuedTracks[i], _envSfxQueuedBlocks[i]); -	_envSfxNumTracksInQueue = 0; -} - -void LoLEngine::snd_loadSoundFile(int track) { -	if (_sound->musicEnabled()) { -		char filename[13]; -		int t = (track - 250) * 3; - -		if (_curMusicFileIndex != _musicTrackMap[t] || _curMusicFileExt != (char)_musicTrackMap[t + 1]) { -			snd_stopMusic(); -			snprintf(filename, sizeof(filename), "LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]); -			_sound->loadSoundFile(filename); -			_curMusicFileIndex = _musicTrackMap[t]; -			_curMusicFileExt = (char)_musicTrackMap[t + 1]; -		} else { -			snd_stopMusic(); -		} -	} else { -		//XXX -	} -} - -int LoLEngine::snd_playTrack(int track) { -	if (track == -1) -		return _lastMusicTrack; - -	int res = _lastMusicTrack; -	_lastMusicTrack = track; - -	if (_sound->musicEnabled()) { -		snd_loadSoundFile(track); -		int t = (track - 250) * 3; -		_sound->playTrack(_musicTrackMap[t + 2]); -	} - -	return res; -} - -int LoLEngine::snd_stopMusic() { -	if (_sound->musicEnabled()) { -		if (_sound->isPlaying()) { -			_sound->beginFadeOut(); -			_system->delayMillis(3 * _tickLength); -		} - -		_sound->haltTrack(); -	} -	return snd_playTrack(-1); -} -  int LoLEngine::characterSays(int track, int charId, bool redraw) {  	if (charId == 1) {  		charId = _selectedCharacter; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 5a82a47cdb..19904fdbb2 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -413,7 +413,7 @@ private:  	void loadTalkFile(int index);  	void snd_playVoiceFile(int track) {}  	bool snd_playCharacterSpeech(int id, int8 speaker, int); -	int snd_characterSpeaking(); +	int snd_updateCharacterSpeech();  	void snd_stopSpeech(bool setFlag);  	void snd_playSoundEffect(int track, int volume);  	void snd_processEnvironmentalSoundEffect(int soundId, int block); @@ -440,6 +440,7 @@ private:  	uint16 _envSfxQueuedBlocks[10];  	int _nextSpeechId;  	int _nextSpeaker; +	Common::List<Audio::AudioStream*> _speechList;  	int _curTlkFile;  	int _speechFlag; diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index ac28d741ca..eafc1f5436 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -56,6 +56,7 @@ MODULE_OBJS := \  	sound_towns.o \  	sound.o \  	sound_lok.o \ +	sound_lol.o \  	sprites.o \  	staticres.o \  	text.o \ diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index a7b3d573b2..85ced707e6 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -1587,7 +1587,7 @@ int LoLEngine::olol_suspendMonster(EMCState *script) {  int LoLEngine::olol_triggerEventOnMouseButtonClick(EMCState *script) {  	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_triggerEventOnMouseButtonClick(%p) (%d)", (const void *)script, stackPos(0));  	gui_notifyButtonListChanged(); -	snd_characterSpeaking(); +	snd_updateCharacterSpeech();  	int f = checkInput(0);  	removeInputTop(); @@ -1980,7 +1980,7 @@ int LoLEngine::olol_characterSays(EMCState *script) {  	if (stackPos(0) != -2)  		return characterSays(stackPos(0), stackPos(1), stackPos(2));  	else -		return snd_characterSpeaking(); +		return snd_updateCharacterSpeech();  }  int LoLEngine::olol_queueSpeech(EMCState *script) { diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp index 95276f58dd..80dca87763 100644 --- a/engines/kyra/script_tim.cpp +++ b/engines/kyra/script_tim.cpp @@ -1108,7 +1108,7 @@ uint16 TIMInterpreter_LoL::processDialogue() {  			}  		} -		if (_vm->snd_characterSpeaking() != 2) { +		if (_vm->snd_updateCharacterSpeech() != 2) {  			//if (_dlgTimer < _system->getMillis()) {  				res = 1;  				if (!_vm->shouldQuit()) { @@ -1201,7 +1201,7 @@ void TIMInterpreter_LoL::update() {  void TIMInterpreter_LoL::checkSpeechProgress() {  	if (_vm->speechEnabled() && _currentTim->procParam > 1 && _currentTim->func[_currentFunc].loopIp) { -		if (_vm->snd_characterSpeaking() != 2) { +		if (_vm->snd_updateCharacterSpeech() != 2) {  			_currentTim->func[_currentFunc].loopIp = 0;  			_currentTim->dlgFunc = _currentFunc;  			advanceToOpcode(21); @@ -1235,7 +1235,7 @@ int TIMInterpreter_LoL::execCommand(int cmd, const uint16 *param) {  int TIMInterpreter_LoL::cmd_setLoopIp(const uint16 *param) {  	if (_vm->speechEnabled()) { -		if (_vm->snd_characterSpeaking() == 2) +		if (_vm->snd_updateCharacterSpeech() == 2)  			_currentTim->func[_currentFunc].loopIp = _currentTim->func[_currentFunc].ip;  		else  			advanceToOpcode(21); @@ -1253,7 +1253,7 @@ int TIMInterpreter_LoL::cmd_continueLoop(const uint16 *param) {  	func.ip = func.loopIp; -	if (_vm->snd_characterSpeaking() != 2) { +	if (_vm->snd_updateCharacterSpeech() != 2) {  		uint16 factor = param[0];  		if (factor) {  			const uint32 random = _vm->_rnd.getRandomNumberRng(0, 0x8000); diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 5b32b69e19..975cff740a 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -66,17 +66,24 @@ bool Sound::voiceFileIsPresent(const char *file) {  	return false;  } -int32 Sound::voicePlay(const char *file, uint8 volume, bool isSfx) { -	char filenamebuffer[25]; +int32 Sound::voicePlay(const char *file, uint8 volume, bool isSfx, bool appendSuffix) { +	int32 ptime = 0; +	Audio::AudioStream *audioStream = getVoiceStream(file, &ptime, appendSuffix); -	int h = 0; -	while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles) -		h++; -	if (h >= kNumChannelHandles) +	if (!audioStream) { +		warning("Couldn't load sound file '%s'", file);  		return 0; +	} -	Audio::AudioStream *audioStream = 0; +	playVoiceStream(audioStream, file, volume, isSfx) ; +	return ptime; +} + +Audio::AudioStream *Sound::getVoiceStream(const char *file, int32 *totalPlayingTime, bool appendSuffix) { +	char filenamebuffer[25]; + +	Audio::AudioStream *audioStream = 0;  	for (int i = 0; _supportedCodecs[i].fileext; ++i) {  		strcpy(filenamebuffer, file);  		strcat(filenamebuffer, _supportedCodecs[i].fileext); @@ -88,9 +95,12 @@ int32 Sound::voicePlay(const char *file, uint8 volume, bool isSfx) {  		break;  	} +	int32 vocStreamPlayTime = 0; +  	if (!audioStream) {  		strcpy(filenamebuffer, file); -		strcat(filenamebuffer, ".VOC"); +		if (appendSuffix) +			strcat(filenamebuffer, ".VOC");  		uint32 fileSize = 0;  		byte *fileData = _vm->resource()->fileData(filenamebuffer, &fileSize); @@ -100,62 +110,25 @@ int32 Sound::voicePlay(const char *file, uint8 volume, bool isSfx) {  		Common::MemoryReadStream vocStream(fileData, fileSize);  		audioStream = Audio::makeVOCStream(vocStream, Audio::Mixer::FLAG_UNSIGNED); -		delete[] fileData; -		fileSize = 0; -	} - -	if (!audioStream) { -		warning("Couldn't load sound file '%s'", file); -		return 0; +		if (audioStream) +			vocStreamPlayTime = vocStream.size() * 1000 / audioStream->getRate(); +	} else { +		vocStreamPlayTime = audioStream->getTotalPlayTime();  	} - -	_soundChannels[h].file = file; -	_mixer->playInputStream(isSfx ? Audio::Mixer::kSFXSoundType : Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, audioStream, -1, volume); - -	return audioStream->getTotalPlayTime(); +  +	*totalPlayingTime = vocStreamPlayTime; +	return audioStream;  } -uint32 Sound::voicePlayFromList(Common::List<const char*> fileList) { +void Sound::playVoiceStream(Audio::AudioStream *stream, const char *handleName, uint8 volume, bool isSfx) {  	int h = 0;  	while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles)  		h++;  	if (h >= kNumChannelHandles) -		return 0; - -	Audio::AppendableAudioStream *out = Audio::makeAppendableAudioStream(22050, Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED); -	uint32 totalPlayTime = 0; - -	for (Common::List<const char*>::iterator i = fileList.begin(); i != fileList.end(); i++) { -		Common::SeekableReadStream *file = _vm->resource()->createReadStream(*i); - -		if (!file) { -			warning("Couldn't load voice file: %s", *i); -			continue; -		} - -		int size, rate; -		uint8 *data = Audio::loadVOCFromStream(*file, size, rate); -		delete file; - -		// FIXME/HACK: While loadVOCStream uses malloc / realloc, -		// AppendableAudioStream uses delete[] to free the passed buffer. -		// As a consequence we just 'move' the data to a buffer allocated -		// via new[]. -		uint8 *vocBuffer = new uint8[size]; -		assert(vocBuffer); -		memcpy(vocBuffer, data, size); -		free(data); - -		out->queueBuffer(vocBuffer, size); -		totalPlayTime += size; -	} - -	totalPlayTime = (totalPlayTime * 1000) / 22050; -	out->finish(); +		return; -	_soundChannels[h].file = *fileList.begin(); -	_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, out); -	return totalPlayTime; +	_soundChannels[h].file = handleName; +	_mixer->playInputStream(isSfx ? Audio::Mixer::kSFXSoundType : Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, stream, -1, volume);  }  void Sound::voiceStop(const char *file) { diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index 52334806ad..bf121ede2b 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -195,15 +195,11 @@ public:  	 * @param isSfx		marks file as sfx instead of voice  	 * @return playtime of the voice file (-1 marks unknown playtime)  	 */ -	virtual int32 voicePlay(const char *file, uint8 volume = 255, bool isSfx = false); +	virtual int32 voicePlay(const char *file, uint8 volume = 255, bool isSfx = false, bool appendSuffix = true); +	 +	Audio::AudioStream *getVoiceStream(const char *file, int32 *totalPlayingTime, bool appendSuffix = true); -	/** -	 * Queues the specified voice files in an AppendableAudioStream -	 * and plays them. -	 * -	 * @param fileList:	files to be played -	 */ -	virtual uint32 voicePlayFromList(Common::List<const char*> fileList); +	void playVoiceStream(Audio::AudioStream * stream, const char *handleName, uint8 volume = 255, bool isSfx = false);  	/**  	 * Checks if a voice is being played. @@ -465,7 +461,7 @@ public:  	void haltTrack();  	void beginFadeOut(); -	int32 voicePlay(const char *file, uint8 volume = 255, bool isSfx = false) { return -1; } +	int32 voicePlay(const char *file, uint8 volume = 255, bool isSfx = false, bool appendSuffix = true) { return -1; }  	void playSoundEffect(uint8);  protected: @@ -492,7 +488,7 @@ public:  	void haltTrack();  	void beginFadeOut(); -	int32 voicePlay(const char *file, uint8 volume = 255, bool isSfx = false); +	int32 voicePlay(const char *file, uint8 volume = 255, bool isSfx = false, bool appendSuffix = true);  	void playSoundEffect(uint8 track);  protected: diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp new file mode 100644 index 0000000000..862788d524 --- /dev/null +++ b/engines/kyra/sound_lol.cpp @@ -0,0 +1,317 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/sound.h" +#include "kyra/lol.h" +#include "kyra/resource.h" + +namespace Kyra { + +bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) { +	if (!_speechFlag) +		return false; + +	if (speaker < 65) { +		if (_characters[speaker].flags & 1) +			speaker = (int) _characters[speaker].name[0]; +		else +			speaker = 0; +	} + +	if (_lastSpeechId == id && speaker == _lastSpeaker) +		return true; + +	_lastSpeechId = id; +	_lastSpeaker = speaker; +	_nextSpeechId = _nextSpeaker = -1; +	 +	char pattern1[8]; +	char pattern2[5]; +	char file1[13]; +	char file2[13]; +	char file3[13]; +	file3[0] = 0; + +	Common::List<const char*> playList; + +	snprintf(pattern2, sizeof(pattern2), "%02d", id & 0x4000 ? 0 : _curTlkFile); + +	if (id & 0x4000) { +		snprintf(pattern1, sizeof(pattern1), "%03X", id & 0x3fff); +	} else if (id < 1000) { +		snprintf(pattern1, sizeof(pattern1), "%03d", id); +	} else { +		snprintf(file3, sizeof(file3), "@%04d%c.%s", id - 1000, (char)speaker, pattern2); +		if (_res->exists(file3)) { +			char *f = new char[strlen(file3) + 1]; +			strcpy(f, file3); +			playList.push_back(f); +		} +	} + +	if (!file3[0]) { +		for (char i = 0; ; i++) { +			char symbol = '0' + i; +			snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, symbol, pattern2); +			snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', symbol, pattern2); +			if (_res->exists(file1)) { +				char *f = new char[strlen(file1) + 1]; +				strcpy(f, file1); +				playList.push_back(f); +			} else if (_res->exists(file2)) { +				char *f = new char[strlen(file2) + 1]; +				strcpy(f, file2); +				playList.push_back(f); +			} else { +				break; +			} +		} +	} + +	if (playList.empty()) +		return false; + +	while (_sound->voiceIsPlaying(_activeVoiceFile)) +		delay(_tickLength, true, false); + +	while (_sound->allVoiceChannelsPlaying()) +		delay(_tickLength, false, true); + +	strcpy(_activeVoiceFile, *playList.begin()); + +	_activeVoiceFileTotalTime = 0; +	for (Common::List<Audio::AudioStream *>::iterator i = _speechList.begin(); i != _speechList.end(); ++i) +		delete *i; +	_speechList.clear(); + +	int32 pt = 0; +	for (Common::List<const char*>::iterator i = playList.begin(); i != playList.end(); ++i) { +		Audio::AudioStream *a = _sound->getVoiceStream(*i, &pt, false); +		_speechList.push_back(a); +		_activeVoiceFileTotalTime += pt; +	} + +	//_activeVoiceFileTotalTime = _sound->voicePlay(_activeVoiceFile, 255, false, false); +	_sound->playVoiceStream(*_speechList.begin(), _activeVoiceFile); +	_speechList.pop_front(); + +	playList.clear(); +	//for (Common::List<const char*>::iterator i = _speechPlayList.begin(); i != _speechPlayList.end(); ++i) +	//	_activeVoiceFileTotalTime += _sound->getTotalPlayTime(*i, false); +	/*if (_speechPlayList.begin() != _speechPlayList.end()) +		_activeVoiceFileTotalTime |= 0x80000000;*/ + +	if (!_activeVoiceFileTotalTime) +		return false; + +	_tim->_abortFlag = 0; + +	return true; +} + +int LoLEngine::snd_updateCharacterSpeech() { +	if (_sound->voiceIsPlaying(_activeVoiceFile)) +		return 2; + +	if (_speechList.begin() != _speechList.end()) { +		_sound->playVoiceStream(*_speechList.begin(), _activeVoiceFile); +		_speechList.pop_front(); +		return 2; + +	} else if (_nextSpeechId != -1) { +		_lastSpeechId = _lastSpeaker = -1; +		_activeVoiceFileTotalTime = 0; +		if (snd_playCharacterSpeech(_nextSpeechId, _nextSpeaker, 0)) +			return 2; +	} + +	_lastSpeechId = _lastSpeaker = -1; +	_activeVoiceFileTotalTime = 0; + +	return 0; +} + +void LoLEngine::snd_stopSpeech(bool setFlag) { +	if (!_sound->voiceIsPlaying(_activeVoiceFile)) +		return; + +	//_dlgTimer = 0; +	_sound->voiceStop(_activeVoiceFile); +	_activeVoiceFileTotalTime = 0; +	_nextSpeechId = _nextSpeaker = -1; + +	for (Common::List<Audio::AudioStream *>::iterator i = _speechList.begin(); i != _speechList.end(); ++i) +		delete *i; +	_speechList.clear(); + +	if (setFlag) +		_tim->_abortFlag = 1; +} + +void LoLEngine::snd_playSoundEffect(int track, int volume) { +	if (track == 1 && (_lastSfxTrack == -1 || _lastSfxTrack == 1)) +		return; + +	_lastSfxTrack = track; +	if (track == -1) +		return; + +	int16 volIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2 + 1]); + +	if (volIndex > 0) +		volume = (volIndex * volume) >> 8; +	else if (volIndex < 0) +		volume = -volIndex; + +	// volume TODO +	volume = 254 - volume; + +	int16 vocIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2]); + +	bool hasVocFile = false; +	if (vocIndex != -1) { +		if (scumm_stricmp(_ingameSoundList[vocIndex], "EMPTY")) +			hasVocFile = true; +	} + +	if (hasVocFile) { +		_sound->voicePlay(_ingameSoundList[vocIndex], volume & 0xff, true); +	} else if (_flags.platform == Common::kPlatformPC) { +		if (_sound->getSfxType() == Sound::kMidiMT32) +			track = track < _ingameMT32SoundIndexSize ? _ingameMT32SoundIndex[track] - 1 : -1; +		else if (_sound->getSfxType() == Sound::kMidiGM) +			track = track < _ingameGMSoundIndexSize ? _ingameGMSoundIndex[track] - 1: -1; + +		if (track == 168) +			track = 167; + +		if (track != -1) +			KyraEngine_v1::snd_playSoundEffect(track, volume); +	} +} + +void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { +	if (!_sound->sfxEnabled()) +		return; + +	if (_environmentSfx) +		snd_playSoundEffect(_environmentSfx, _environmentSfxVol); + +	int dist = 0; +	if (block) { +		dist = getMonsterDistance(_currentBlock, block); +		if (dist > _envSfxDistThreshold) { +			_environmentSfx = 0; +			return; +		} +	} + +	_environmentSfx = soundId; +	_environmentSfxVol = (15 - ((block || dist < 2) ? dist : 0)) << 4; + +	if (block != _currentBlock) { +		static const int8 blockShiftTable[] = { -32, -31, 1, 33, 32, 31, -1, -33 }; +		uint16 cbl = _currentBlock; + +		for (int i = 3; i > 0; i--) { +			int dir = calcMonsterDirection(cbl & 0x1f, cbl >> 5, block & 0x1f, block >> 5); +			cbl += blockShiftTable[dir]; +			if (cbl != block) { +				if (testWallFlag(cbl, 0, 1)) +					_environmentSfxVol >>= 1; +			} +		} +	} + +	if (!soundId || _sceneUpdateRequired) +		return; + +	snd_processEnvironmentalSoundEffect(0, 0); +} + +void LoLEngine::snd_queueEnvironmentalSoundEffect(int soundId, int block) { +	if (_envSfxUseQueue && _envSfxNumTracksInQueue < 10) { +		_envSfxQueuedTracks[_envSfxNumTracksInQueue] = soundId; +		_envSfxQueuedBlocks[_envSfxNumTracksInQueue] = block; +		_envSfxNumTracksInQueue++; +	} else { +		snd_processEnvironmentalSoundEffect(soundId, block); +	} +} + +void LoLEngine::snd_playQueuedEffects() { +	for (int i = 0; i < _envSfxNumTracksInQueue; i++) +		snd_processEnvironmentalSoundEffect(_envSfxQueuedTracks[i], _envSfxQueuedBlocks[i]); +	_envSfxNumTracksInQueue = 0; +} + +void LoLEngine::snd_loadSoundFile(int track) { +	if (_sound->musicEnabled()) { +		char filename[13]; +		int t = (track - 250) * 3; + +		if (_curMusicFileIndex != _musicTrackMap[t] || _curMusicFileExt != (char)_musicTrackMap[t + 1]) { +			snd_stopMusic(); +			snprintf(filename, sizeof(filename), "LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]); +			_sound->loadSoundFile(filename); +			_curMusicFileIndex = _musicTrackMap[t]; +			_curMusicFileExt = (char)_musicTrackMap[t + 1]; +		} else { +			snd_stopMusic(); +		} +	} else { +		//XXX +	} +} + +int LoLEngine::snd_playTrack(int track) { +	if (track == -1) +		return _lastMusicTrack; + +	int res = _lastMusicTrack; +	_lastMusicTrack = track; + +	if (_sound->musicEnabled()) { +		snd_loadSoundFile(track); +		int t = (track - 250) * 3; +		_sound->playTrack(_musicTrackMap[t + 2]); +	} + +	return res; +} + +int LoLEngine::snd_stopMusic() { +	if (_sound->musicEnabled()) { +		if (_sound->isPlaying()) { +			_sound->beginFadeOut(); +			_system->delayMillis(3 * _tickLength); +		} + +		_sound->haltTrack(); +	} +	return snd_playTrack(-1); +} + +} // end of namespace Kyra diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index f96e37b94f..2340f81aa8 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -4231,7 +4231,7 @@ void SoundTownsPC98_v2::beginFadeOut() {  	haltTrack();  } -int32 SoundTownsPC98_v2::voicePlay(const char *file, uint8, bool) { +int32 SoundTownsPC98_v2::voicePlay(const char *file, uint8, bool, bool) {  	static const uint16 rates[] =	{ 0x10E1, 0x0CA9, 0x0870, 0x0654, 0x0438, 0x032A, 0x021C, 0x0194 };  	static const char patternHOF[] = "%s.PCM";  	static const char patternLOL[] = "%s.VOC"; diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp index 38b6078298..3e1ee84dec 100644 --- a/engines/kyra/text_lol.cpp +++ b/engines/kyra/text_lol.cpp @@ -640,7 +640,7 @@ void TextDisplayer_LoL::textPageBreak() {  			_vm->update();  			if (_vm->_speechFlag) { -				if (((_vm->_system->getMillis() > speechPartTime) || (_vm->snd_characterSpeaking() != 2)) && speechPartTime) { +				if (((_vm->_system->getMillis() > speechPartTime) || (_vm->snd_updateCharacterSpeech() != 2)) && speechPartTime) {  					loop = false;  					inputFlag = 43;  					break; | 
