mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-17 23:44:22 +00:00
fix for bug #769744 (COMI: Trying to append to a nonexistant stream)
svn-id: r9025
This commit is contained in:
parent
42d0b2e6f7
commit
bb87787314
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
124
scumm/sound.cpp
124
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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user