diff options
-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); |