diff --git a/scumm/smush/channel.h b/scumm/smush/channel.h index ecd9d1b8ac3..722a6191d6b 100644 --- a/scumm/smush/channel.h +++ b/scumm/smush/channel.h @@ -34,7 +34,7 @@ public: virtual ~SmushChannel() {}; virtual bool appendData(Chunk &b, int32 size) = 0; - virtual bool setParameters(int32, int32, int32, int32) = 0; + virtual bool setParameters(int32, int32, int32, int32, int32) = 0; virtual bool checkParameters(int32, int32, int32, int32, int32) = 0; virtual bool isTerminated() const = 0; virtual int32 availableSoundData() const = 0; @@ -62,6 +62,7 @@ private: int32 _tbufferSize; byte *_sbuffer; int32 _sbufferSize; + bool _keepSize; protected: void handleStrk(Chunk &c); @@ -75,7 +76,7 @@ public: SaudChannel(int32 track, int32 freq); virtual ~SaudChannel(); bool isTerminated() const; - bool setParameters(int32 duration, int32 flags, int32 vol1, int32 vol2); + bool setParameters(int32 duration, int32 flags, int32 vol1, int32 vol2, int32 index); bool checkParameters(int32 index, int32 duration, int32 flags, int32 vol1, int32 vol2); bool appendData(Chunk &b, int32 size); int32 availableSoundData() const; @@ -123,7 +124,7 @@ public: ImuseChannel(int32 track, int32 freq); virtual ~ImuseChannel(); bool isTerminated() const; - bool setParameters(int32 nbframes, int32 size, int32 track_flags, int32 unk1); + bool setParameters(int32 nbframes, int32 size, int32 track_flags, int32 unk1, int32); bool checkParameters(int32 index, int32 nbframes, int32 size, int32 track_flags, int32 unk1); bool appendData(Chunk &b, int32 size); int32 availableSoundData() const; diff --git a/scumm/smush/imuse_channel.cpp b/scumm/smush/imuse_channel.cpp index 2b143903937..2c6762008ca 100644 --- a/scumm/smush/imuse_channel.cpp +++ b/scumm/smush/imuse_channel.cpp @@ -51,7 +51,7 @@ bool ImuseChannel::isTerminated() const { return (_dataSize <= 0 && _sbuffer == 0); } -bool ImuseChannel::setParameters(int32 nb, int32 size, int32 flags, int32 unk1) { +bool ImuseChannel::setParameters(int32 nb, int32 size, int32 flags, int32 unk1, int32) { if ((flags == 1) || (flags == 2) || (flags == 3)) { _volume = 127; } else if ((flags >= 100) && (flags <= 163)) { diff --git a/scumm/smush/saud_channel.cpp b/scumm/smush/saud_channel.cpp index c06cee0ce13..e00ec873f9b 100644 --- a/scumm/smush/saud_channel.cpp +++ b/scumm/smush/saud_channel.cpp @@ -95,7 +95,12 @@ bool SaudChannel::processBuffer() { assert(_sbuffer == 0); assert(_sbufferSize == 0); - if (_inData) { + if (_keepSize) { + _sbufferSize = _tbufferSize; + _sbuffer = _tbuffer; + _tbufferSize = 0; + _tbuffer = 0; + } else if (_inData) { if (_dataSize < _tbufferSize) { int32 offset = _dataSize; while (handleSubTags(offset)); @@ -104,7 +109,8 @@ bool SaudChannel::processBuffer() { if (offset < _tbufferSize) { int new_size = _tbufferSize - offset; _tbuffer = new byte[new_size]; - if (!_tbuffer) error("SaudChannel failed to allocate memory"); + if (!_tbuffer) + error("SaudChannel failed to allocate memory"); memcpy(_tbuffer, _sbuffer + offset, new_size); _tbufferSize = new_size; } else { @@ -160,12 +166,13 @@ SaudChannel::SaudChannel(int32 track, int32 freq) : _tbuffer(0), _tbufferSize(0), _sbuffer(0), - _sbufferSize(0) -{ + _sbufferSize(0), + _keepSize(false) { } SaudChannel::~SaudChannel() { - if (_tbuffer) delete []_tbuffer; + if (_tbuffer) + delete []_tbuffer; if (_sbuffer) { warning("this should never happen !!!! (_sbuffer not NULL here)"); delete []_sbuffer; @@ -203,12 +210,17 @@ void SaudChannel::recalcVolumeTable() { } } -bool SaudChannel::setParameters(int32 nb, int32 flags, int32 volume, int32 balance) { +bool SaudChannel::setParameters(int32 nb, int32 flags, int32 volume, int32 balance, int32 index) { _nbframes = nb; _flags = flags; // bit 7 == IS_VOICE, bit 6 == IS_BACKGROUND_MUSIC, other ?? _volume = volume; _balance = balance; - _index = 0; + _index = index; + if (index != 0) { + _dataSize = -2; + _keepSize = true; + _inData = true; + } recalcVolumeTable(); return true; } @@ -231,16 +243,20 @@ bool SaudChannel::checkParameters(int32 index, int32 nb, int32 flags, int32 volu bool SaudChannel::appendData(Chunk &b, int32 size) { if (_dataSize == -1) { assert(size > 8); - Chunk::type saud_type = b.getDword(); saud_type = SWAP_BYTES_32(saud_type); - uint32 saud_size = b.getDword(); saud_size = SWAP_BYTES_32(saud_size); - if (saud_type != TYPE_SAUD) error("Invalid Chunk for SaudChannel : %X", saud_type); + Chunk::type saud_type = b.getDword(); + saud_type = SWAP_BYTES_32(saud_type); + uint32 saud_size = b.getDword(); + saud_size = SWAP_BYTES_32(saud_size); + if (saud_type != TYPE_SAUD) + error("Invalid Chunk for SaudChannel : %X", saud_type); size -= 8; _dataSize = -2; } if (_tbuffer) { byte *old = _tbuffer; _tbuffer = new byte[_tbufferSize + size]; - if (!_tbuffer) error("saud_channel failed to allocate memory"); + if (!_tbuffer) + error("saud_channel failed to allocate memory"); memcpy(_tbuffer, old, _tbufferSize); delete []old; b.read(_tbuffer + _tbufferSize, size); @@ -248,7 +264,8 @@ bool SaudChannel::appendData(Chunk &b, int32 size) { } else { _tbufferSize = size; _tbuffer = new byte[_tbufferSize]; - if (!_tbuffer) error("saud_channel failed to allocate memory"); + if (!_tbuffer) + error("saud_channel failed to allocate memory"); b.read(_tbuffer, _tbufferSize); } return processBuffer(); @@ -263,7 +280,8 @@ void SaudChannel::getSoundData(int16 *snd, int32 size) { snd[2 * i] = _voltable[0][_sbuffer[i] ^ 0x80]; snd[2 * i + 1] = _voltable[1][_sbuffer[i] ^ 0x80]; } - _dataSize -= size; + if (!_keepSize) + _dataSize -= size; delete []_sbuffer; _sbuffer = 0; _sbufferSize = 0; diff --git a/scumm/smush/smush_player.cpp b/scumm/smush/smush_player.cpp index 65684a4d5fc..62bdaecbbd6 100644 --- a/scumm/smush/smush_player.cpp +++ b/scumm/smush/smush_player.cpp @@ -233,6 +233,7 @@ SmushPlayer::SmushPlayer(ScummEngine *scumm, int speed, bool subtitles) { _soundFrequency = 22050; _speed = speed; _insanity = false; + _midleAudio = false; } SmushPlayer::~SmushPlayer() { @@ -315,11 +316,15 @@ void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frame c = new SaudChannel(track_id, _soundFrequency); _smixer->addChannel(c); } - if (index == 0) { - c->setParameters(max_frames, flags, vol, bal); - } else { + + if ((_midleAudio) && (index != 0)) { + c->setParameters(max_frames, flags, vol, bal, index); + } else if (index == 0) { + c->setParameters(max_frames, flags, vol, bal, index); + } else { c->checkParameters(index, max_frames, flags, vol, bal); } + _midleAudio = false; c->appendData(b, size); } @@ -408,7 +413,7 @@ void SmushPlayer::handleIACT(Chunk &b) { _smixer->addChannel(c); } if (index == 0) - c->setParameters(nbframes, size, track_flags, unknown); + c->setParameters(nbframes, size, track_flags, unknown, 0); else c->checkParameters(index, nbframes, size, track_flags, unknown); c->appendData(b, bsize); @@ -982,6 +987,7 @@ void SmushPlayer::seekSan(const char *file, const char *directory, int32 pos) { if (pos != 8) { _base->reinit(); _base->seek(pos, FileChunk::seek_start); + _midleAudio = true; } // FIXME: is this really applicable for FLU files? HACK diff --git a/scumm/smush/smush_player.h b/scumm/smush/smush_player.h index b1192515526..5d9425a33a5 100644 --- a/scumm/smush/smush_player.h +++ b/scumm/smush/smush_player.h @@ -68,6 +68,7 @@ private: byte *_dst; bool _updateNeeded; bool _insanity; + bool _midleAudio; public: SmushPlayer(ScummEngine *, int, bool);