diff options
| author | Max Horn | 2003-07-14 21:37:45 +0000 | 
|---|---|---|
| committer | Max Horn | 2003-07-14 21:37:45 +0000 | 
| commit | bb87787314d90487d5c4762f94abd944cca196bb (patch) | |
| tree | 1d470238cdc391ffc9259f057791efa7f72d7925 | |
| parent | 42d0b2e6f79378558832857b3f1ece4ea57164bf (diff) | |
| download | scummvm-rg350-bb87787314d90487d5c4762f94abd944cca196bb.tar.gz scummvm-rg350-bb87787314d90487d5c4762f94abd944cca196bb.tar.bz2 scummvm-rg350-bb87787314d90487d5c4762f94abd944cca196bb.zip  | |
fix for bug #769744 (COMI: Trying to append to a nonexistant stream)
svn-id: r9025
| -rw-r--r-- | scumm/script_v6.cpp | 12 | ||||
| -rw-r--r-- | scumm/script_v8.cpp | 9 | ||||
| -rw-r--r-- | scumm/sound.cpp | 124 | ||||
| -rw-r--r-- | scumm/sound.h | 15 | ||||
| -rw-r--r-- | scumm/string.cpp | 9 | 
5 files changed, 77 insertions, 92 deletions
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index 6d2f38463c..4c798b0ee2 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -2251,11 +2251,9 @@ void Scumm_v6::o6_talkActor() {  		}  		pointer[j] = 0; -		// Stop any talking that's still going on -		if (_sound->_talkChannel > -1) -			_mixer->stop(_sound->_talkChannel); +		// Play speech +		_sound->playBundleSound(pointer, &_sound->_talkChannelHandle); -		_sound->_talkChannel = _sound->playBundleSound(pointer);  		_messagePtr = _transText;  	} @@ -3108,11 +3106,9 @@ void Scumm_v6::decodeParseString(int m, int n) {  			}  			pointer[j] = 0; -			// Stop any talking that's still going on -			if (_sound->_talkChannel > -1) -				_mixer->stop(_sound->_talkChannel); +			// Play speech +			_sound->playBundleSound(pointer, &_sound->_talkChannelHandle); -			_sound->_talkChannel = _sound->playBundleSound(pointer);  			_messagePtr = _transText;  		} diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index 9edac12f6c..7da8f8a906 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -513,13 +513,8 @@ void Scumm_v8::decodeParseString(int m, int n) {  			}  			pointer[j] = 0; -			int new_sound = _sound->playBundleSound(pointer); -			if (new_sound != -1) { -				// Stop any talking that's still going on -				if (_sound->_talkChannel > -1) -					_mixer->stop(_sound->_talkChannel); -				_sound->_talkChannel = new_sound; -			} +			// Play speech +			_sound->playBundleSound(pointer, &_sound->_talkChannelHandle);  			_messagePtr = _transText;  		} diff --git a/scumm/sound.cpp b/scumm/sound.cpp index e934a1bbfc..4ca180acbc 100644 --- a/scumm/sound.cpp +++ b/scumm/sound.cpp @@ -91,7 +91,7 @@ Sound::Sound(Scumm *parent) {  	_musicBundleBufFinal = NULL;  	_musicBundleBufOutput = NULL;  	_musicDisk = 0; -	_talkChannel = -1; +	_talkChannelHandle = 0;  	_current_cache = 0;  	_currentCDSound = 0; @@ -535,14 +535,15 @@ void Sound::processSfxQueues() {  	if (_talk_sound_mode != 0) {  		if (_talk_sound_mode & 1)  			startTalkSound(_talk_sound_a1, _talk_sound_b1, 1); -		if (_talk_sound_mode & 2) -			_talkChannel = startTalkSound(_talk_sound_a2, _talk_sound_b2, 2); +		if (_talk_sound_mode & 2) { +			startTalkSound(_talk_sound_a2, _talk_sound_b2, 2, &_talkChannelHandle); +		}  		_talk_sound_mode = 0;  	}  	if (_scumm->VAR(_scumm->VAR_TALK_ACTOR)) { //_sfxMode & 2) {  		act = _scumm->VAR(_scumm->VAR_TALK_ACTOR); -		finished = (_talkChannel >= 0) && (_scumm->_mixer->_channels[_talkChannel] == NULL); +		finished = !_talkChannelHandle;  		if (act != 0 && (uint) act < 0x80 && !_scumm->_string[0].no_talk_anim) {  			a = _scumm->derefActor(act, "processSfxQueues"); @@ -564,7 +565,6 @@ void Sound::processSfxQueues() {  		if (finished && _scumm->_talkDelay == 0) {  			_scumm->stopTalk();  			_sfxMode &= ~2; -			_talkChannel = -1;  		}  	} @@ -579,14 +579,14 @@ static int compareMP3OffsetTable(const void *a, const void *b) {  	return ((const MP3OffsetTable *)a)->org_offset - ((const MP3OffsetTable *)b)->org_offset;  } -int Sound::startTalkSound(uint32 offset, uint32 b, int mode) { +void Sound::startTalkSound(uint32 offset, uint32 b, int mode, PlayingSoundHandle *handle) {  	int num = 0, i;  	int size;  	byte *sound;  	if (_sfxFile->isOpen() == false) {  		warning("startTalkSound: SFX file is not open"); -		return -1; +		return;  	}  	// FIXME hack until more is known @@ -597,8 +597,8 @@ int Sound::startTalkSound(uint32 offset, uint32 b, int mode) {  		_sfxFile->seek(offset + 48, SEEK_SET);  		sound = (byte *)malloc(b - 64);  		_sfxFile->read(sound, b - 64); -		_scumm->_mixer->playRaw(NULL, sound, b - 64, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); -		return -1; +		_scumm->_mixer->playRaw(handle, sound, b - 64, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); +		return;  	}  	// Some games frequently assume that starting one sound effect will @@ -610,11 +610,13 @@ int Sound::startTalkSound(uint32 offset, uint32 b, int mode) {  	// HACK: Checking for script 99 in Sam & Max is to keep Conroy's song  	// from being interrupted. +	int talkChannel = (_talkChannelHandle - 1);  	if (mode == 1 && (_scumm->_gameId == GID_TENTACLE  		|| (_scumm->_gameId == GID_SAMNMAX && !_scumm->isScriptRunning(99)))) {  		for (i = 0; i < _scumm->_mixer->NUM_CHANNELS; i++) { -			if (i != _talkChannel) +			if (i != talkChannel) {  				_scumm->_mixer->stop(i); +			}  		}  	} @@ -631,7 +633,7 @@ int Sound::startTalkSound(uint32 offset, uint32 b, int mode) {  		if (result == NULL) {  			warning("startTalkSound: did not find sound at offset %d !", offset); -			return -1; +			return;  		}  		if (2 * num != result->num_tags) {  			warning("startTalkSound: number of tags do not match (%d - %d) !", b, @@ -656,15 +658,12 @@ int Sound::startTalkSound(uint32 offset, uint32 b, int mode) {  	_curSoundPos = 0;  	_mouthSyncMode = true; -	return startSfxSound(_sfxFile, size); +	startSfxSound(_sfxFile, size, handle);  }  void Sound::stopTalkSound() {  	if (_sfxMode & 2) { -		if (_talkChannel != -1) { -			_scumm->_mixer->stop(_talkChannel); -			_talkChannel = -1; -		} +		_scumm->_mixer->stopHandle(_talkChannelHandle);  		_sfxMode &= ~2;  	}  } @@ -904,7 +903,7 @@ void Sound::pauseSounds(bool pause) {  	}  } -int Sound::startSfxSound(File *file, int file_size) { +void Sound::startSfxSound(File *file, int file_size, PlayingSoundHandle *handle) {  	char ident[8];  	int block_type;  	byte work[8]; @@ -913,7 +912,7 @@ int Sound::startSfxSound(File *file, int file_size) {  	byte *data;  	if (_scumm->_noDigitalSamples) -		return -1; +		return;  	if (file_size > 0) {  		int alloc_size = file_size; @@ -926,12 +925,12 @@ int Sound::startSfxSound(File *file, int file_size) {  		if (file->read(data, file_size) != (uint)file_size) {  			/* no need to free the memory since error will shut down */  			error("startSfxSound: cannot read %d bytes", size); -			return -1;  		}  		if (_vorbis_mode) -			return playSfxSound_Vorbis(data, file_size); +			playSfxSound_Vorbis(data, file_size, handle);  		else -			return playSfxSound_MP3(data, file_size); +			playSfxSound_MP3(data, file_size, handle); +		return;  	}  	if (file->read(ident, 8) != 8) @@ -944,13 +943,13 @@ int Sound::startSfxSound(File *file, int file_size) {  	} else {  	invalid:;  		warning("startSfxSound: invalid header"); -		return -1; +		return;  	}  	block_type = file->readByte();  	if (block_type != 1) {  		warning("startSfxSound: Expecting block_type == 1, got %d", block_type); -		return -1; +		return;  	}  	file->read(work, 3); @@ -961,22 +960,20 @@ int Sound::startSfxSound(File *file, int file_size) {  	if (comp != 0) {  		warning("startSfxSound: Unsupported compression type %d", comp); -		return -1; +		return;  	}  	data = (byte *)malloc(size);  	if (data == NULL) {  		error("startSfxSound: out of memory"); -		return -1;  	}  	if (file->read(data, size) != size) {  		/* no need to free the memory since error will shut down */  		error("startSfxSound: cannot read %d bytes", size); -		return -1;  	} -	return playSfxSound(data, size, 1000000 / (256 - rate), true); +	playSfxSound(data, size, 1000000 / (256 - rate), true, handle);  }  File *Sound::openSfxFile() { @@ -1288,13 +1285,13 @@ void Sound::bundleMusicHandler(Scumm *scumm) {  	free(buffer);  } -int Sound::playBundleSound(char *sound) { -	byte *ptr = 0, *orig_ptr; +void Sound::playBundleSound(char *sound, PlayingSoundHandle *handle) { +	byte *ptr = 0, *orig_ptr = 0;  	byte *final;  	bool result;  	if (_scumm->_noDigitalSamples) -		return -1;	 +		return;	  	if (_scumm->_gameId == GID_CMI) {  		char voxfile[20]; @@ -1312,9 +1309,8 @@ int Sound::playBundleSound(char *sound) {  	else  		error("Don't know which bundle file to load"); -	if (!result) { -		return -1; -	} +	if (!result) +		return;  	int32 rate = 22050, channels, output_size = 0;  	int32 tag, size = -1, bits = 0; @@ -1378,44 +1374,42 @@ int Sound::playBundleSound(char *sound) {  	final = (byte *)malloc(size);  	memcpy(final, ptr, size); -	free(orig_ptr);  	if (_scumm->_actorToPrintStrFor != 0xFF && _scumm->_actorToPrintStrFor != 0) {  		Actor *a = _scumm->derefActor(_scumm->_actorToPrintStrFor, "playBundleSound");  		rate = (rate * a->talkFrequency) / 256;  	} +	// Stop any sound currently playing on the given handle +	if (handle) +		_scumm->_mixer->stopHandle(*handle); +  	if (bits == 8) { -		return _scumm->_mixer->playRaw(NULL, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); -	} else if (bits == 16){ -		return _scumm->_mixer->playRaw(NULL, final, size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE); +		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); +	} else if (bits == 16) { +		_scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE);  	} else {  		warning("Sound::playBundleSound() to do more options to playRaw..."); -		return -1;  	}  bail: -	if (orig_ptr) -		free(orig_ptr); -	return -1; +	free(orig_ptr);  } -int Sound::playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned) { +void Sound::playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned, PlayingSoundHandle *handle) {  	if (_soundsPaused) -		return -1; +		return;  	byte flags = SoundMixer::FLAG_AUTOFREE;  	if (isUnsigned)  		flags |= SoundMixer::FLAG_UNSIGNED; -	return _scumm->_mixer->playRaw(NULL, sound, size, rate, flags); +	_scumm->_mixer->playRaw(handle, sound, size, rate, flags);  } -int Sound::playSfxSound_MP3(void *sound, uint32 size) { +void Sound::playSfxSound_MP3(void *sound, uint32 size, PlayingSoundHandle *handle) {  #ifdef USE_MAD -	if (_soundsPaused || _scumm->_noDigitalSamples) -		return -1; -	return _scumm->_mixer->playMP3(NULL, sound, size, SoundMixer::FLAG_AUTOFREE); +	if (!_soundsPaused && !_scumm->_noDigitalSamples) +		_scumm->_mixer->playMP3(handle, sound, size, SoundMixer::FLAG_AUTOFREE);  #endif -	return -1;  }  #ifdef USE_VORBIS @@ -1480,27 +1474,23 @@ static ov_callbacks data_wrap = {  };  #endif -int Sound::playSfxSound_Vorbis(void *sound, uint32 size) { +void Sound::playSfxSound_Vorbis(void *sound, uint32 size, PlayingSoundHandle *handle) {  #ifdef USE_VORBIS -	if (_soundsPaused || _scumm->_noDigitalSamples) -		return -1; - -	OggVorbis_File *ov_file = new OggVorbis_File; -	data_file_info *f = new data_file_info; -	f->data = (char *) sound; -	f->size = size; -	f->curr_pos = 0; - -	if (ov_open_callbacks((void *) f, ov_file, NULL, 0, data_wrap) < 0) { -		warning("Invalid file format"); -		delete ov_file; -		delete f; -		return -1; +	if (!_soundsPaused && !_scumm->_noDigitalSamples) { +		OggVorbis_File *ov_file = new OggVorbis_File; +		data_file_info *f = new data_file_info; +		f->data = (char *) sound; +		f->size = size; +		f->curr_pos = 0; +	 +		if (ov_open_callbacks((void *) f, ov_file, NULL, 0, data_wrap) < 0) { +			warning("Invalid file format"); +			delete ov_file; +			delete f; +		} else +			_scumm->_mixer->playVorbis(handle, ov_file, 0, false);  	} - -	return _scumm->_mixer->playVorbis(NULL, ov_file, 0, false);  #endif -	return -1;  }  // We use a real timer in an attempt to get better sync with CD tracks. This is diff --git a/scumm/sound.h b/scumm/sound.h index fc9f6ab942..6214475dcd 100644 --- a/scumm/sound.h +++ b/scumm/sound.h @@ -22,6 +22,7 @@  #define SOUND_H  #include "scummsys.h" +#include "sound/mixer.h"  class Bundle;  class DigitalTrackInfo; @@ -100,7 +101,7 @@ protected:  public:  	int32 _bundleMusicPosition; -	int _talkChannel;	/* Mixer channel actor is talking on */ +	PlayingSoundHandle _talkChannelHandle;	// Handle of mixer channel actor is talking on  	bool _soundsPaused;  	byte _sfxMode; @@ -118,7 +119,7 @@ public:  	void processSoundQues();  	void playSound(int sound);  	void processSfxQueues(); -	int startTalkSound(uint32 offset, uint32 b, int mode); +	void startTalkSound(uint32 offset, uint32 b, int mode, PlayingSoundHandle *handle = NULL);  	void stopTalkSound();  	bool isMouthSyncOff(uint pos);  	int isSoundRunning(int sound) const; @@ -135,7 +136,7 @@ public:  	void pauseBundleMusic(bool state);  	void bundleMusicHandler(Scumm *scumm);  	void stopBundleMusic(); -	int playBundleSound(char *sound); +	void playBundleSound(char *sound, PlayingSoundHandle *handle);  	uint32 decode12BitsSample(byte *src, byte **dst, uint32 size, bool stereo); @@ -152,12 +153,12 @@ protected:  	void clearSoundQue();  	File *openSfxFile(); -	int startSfxSound(File *file, int file_size); +	void startSfxSound(File *file, int file_size, PlayingSoundHandle *handle);  	void stopSfxSound();  	bool isSfxFinished() const; -	int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned); -	int playSfxSound_MP3(void *sound, uint32 size); -	int playSfxSound_Vorbis(void *sound, uint32 size); +	void playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned, PlayingSoundHandle *handle); +	void playSfxSound_MP3(void *sound, uint32 size, PlayingSoundHandle *handle); +	void playSfxSound_Vorbis(void *sound, uint32 size, PlayingSoundHandle *handle);  	int getCachedTrack(int track);  	int playMP3CDTrack(int track, int numLoops, int startFrame, int endFrame); diff --git a/scumm/string.cpp b/scumm/string.cpp index 08ca156ee6..4ebe58f127 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -153,7 +153,7 @@ void Scumm::CHARSET_1() {  		// FIXME: DIG and CMI never set sfxMode or any actor talk data...  		// This hack will force the backup cutoff system to be used instead,  		// unless the talkChannel is null (eg, this string has no sound attached) -		if ((_gameId == GID_CMI || _gameId == GID_DIG) && (_sound->_talkChannel >= 0)) +		if ((_gameId == GID_CMI || _gameId == GID_DIG) && _sound->_talkChannelHandle)  			return;  		if ((_sound->_sfxMode & 2) == 0) @@ -298,7 +298,7 @@ void Scumm::CHARSET_1() {  			if (_version <= 3) {  				_charset->printChar(c);  			} else { -				if (_noSubtitles && (_haveMsg == 0xFE || _sound->_talkChannel >= 0)) { +				if (_noSubtitles && (_haveMsg == 0xFE || _sound->_talkChannelHandle)) {  					// Subtitles are turned off, and there is a voice version  					// of this message -> don't print it.   				} else @@ -594,7 +594,10 @@ void Scumm::addVerbToStack(int var)  							pointer[j++] = ptr[i];  					}  					pointer[j] = 0; -					_sound->_talkChannel = _sound->playBundleSound(pointer); + +					// Play speech +					_sound->playBundleSound(pointer, &_sound->_talkChannelHandle); +  					addMessageToStack(_transText);  				} else {  					addMessageToStack(ptr);  | 
