aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorMax Horn2003-07-14 21:37:45 +0000
committerMax Horn2003-07-14 21:37:45 +0000
commitbb87787314d90487d5c4762f94abd944cca196bb (patch)
tree1d470238cdc391ffc9259f057791efa7f72d7925 /scumm
parent42d0b2e6f79378558832857b3f1ece4ea57164bf (diff)
downloadscummvm-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
Diffstat (limited to 'scumm')
-rw-r--r--scumm/script_v6.cpp12
-rw-r--r--scumm/script_v8.cpp9
-rw-r--r--scumm/sound.cpp124
-rw-r--r--scumm/sound.h15
-rw-r--r--scumm/string.cpp9
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);