aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorNorbert Lange2009-08-04 19:53:13 +0000
committerNorbert Lange2009-08-04 19:53:13 +0000
commit28210abe7795944f66cc6da09cec44ec2c3d1ba7 (patch)
tree44e3d63255b76ea5c0b36b413eb90d5a3970fe3d /engines
parentfc8e269c364dc8d0104a42047bfe6e34a69f7ff7 (diff)
downloadscummvm-rg350-28210abe7795944f66cc6da09cec44ec2c3d1ba7.tar.gz
scummvm-rg350-28210abe7795944f66cc6da09cec44ec2c3d1ba7.tar.bz2
scummvm-rg350-28210abe7795944f66cc6da09cec44ec2c3d1ba7.zip
fixed hanging intro (and possible other scenes) when music cant be loaded
svn-id: r43054
Diffstat (limited to 'engines')
-rw-r--r--engines/scumm/player_v4a.cpp73
1 files changed, 57 insertions, 16 deletions
diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/player_v4a.cpp
index 6a197f30b6..8c636060a8 100644
--- a/engines/scumm/player_v4a.cpp
+++ b/engines/scumm/player_v4a.cpp
@@ -30,6 +30,37 @@
#include "common/file.h"
+namespace {
+// TODO: move this ingenious class into audiostream.h?
+class FakeAudioStream : public Audio::AudioStream {
+ protected:
+ const int _rate;
+ const int32 _playtime;
+ const bool _stereo;
+ uint32 _remainingSamples;
+
+ public:
+ FakeAudioStream(int rate, bool stereo = true, int32 playtime = Audio::AudioStream::kUnknownPlayTime)
+ : _rate(rate), _playtime(playtime), _stereo(stereo) {
+ _remainingSamples = (playtime < 0) ? (uint32)-1 : (uint32)(((double)_playtime * rate) / 1000);
+ }
+ int readBuffer(int16 *buffer, const int numSamples) {
+ uint32 redSamples = MIN((uint32)numSamples, _remainingSamples);
+ assert((int32)redSamples > 0);
+ memset(buffer, 0, redSamples * 2);
+ if (_playtime > 0)
+ _remainingSamples -= redSamples;
+ return (int)redSamples;
+ }
+
+ bool isStereo() const { return _stereo; }
+ bool endOfData() const { return _remainingSamples == 0; }
+
+ int getRate() const { return _rate; }
+ int32 getTotalPlayTime() const { return _playtime; }
+};
+}
+
namespace Scumm {
Player_V4A::Player_V4A(ScummEngine *scumm, Audio::Mixer *mixer)
@@ -80,12 +111,15 @@ void Player_V4A::setMusicVolume(int vol) {
void Player_V4A::stopAllSounds() {
debug(5, "player_v4a: stopAllSounds");
- _tfmxMusic.stopSong();
- _signal = 0;
- _musicId = 0;
+ if (_initState > 0) {
+ _tfmxMusic.stopSong();
+ _signal = 0;
+ _musicId = 0;
- _tfmxSfx.stopSong();
- clearSfxSlots();
+ _tfmxSfx.stopSong();
+ clearSfxSlots();
+ } else
+ _mixer->stopHandle(_musicHandle);
}
void Player_V4A::stopSound(int nr) {
@@ -94,7 +128,10 @@ void Player_V4A::stopSound(int nr) {
return;
if (nr == _musicId) {
_musicId = 0;
- _tfmxMusic.stopSong();
+ if (_initState > 0)
+ _tfmxMusic.stopSong();
+ else
+ _mixer->stopHandle(_musicHandle);
_signal = 0;
} else {
const int chan = getSfxChan(nr);
@@ -128,9 +165,6 @@ void Player_V4A::startSound(int nr) {
if (!_initState)
_initState = init() ? 1 : -1;
- if (_initState <= 0)
- return;
-
int index = monkeyCommands[val];
const byte type = ptr[6];
if (index < 0) { // SoundFX
@@ -144,7 +178,7 @@ void Player_V4A::startSound(int nr) {
const int chan = _tfmxSfx.doSfx((uint16)index);
if (chan >= 0 && chan < ARRAYSIZE(_sfxSlots))
setSfxSlot(chan, nr, type);
- else
+ else if (_initState > 0)
warning("player_v4a: custom %i is not of required type", index);
// the Tfmx-player newer "ends" the output by itself, so this should be threadsafe
@@ -156,13 +190,20 @@ void Player_V4A::startSound(int nr) {
if (ptr[6] != 0x7F)
warning("player_v4a: Song has wrong type");
- _tfmxMusic.doSong(index);
- _signal = 2;
+ if (_initState > 0) {
+ _tfmxMusic.doSong(index);
+ _signal = 2;
+
+ // the Tfmx-player newer "ends" the output by itself, so this should be threadsafe
+ if (!_mixer->isSoundHandleActive(_musicHandle))
+ _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, &_tfmxMusic, -1, Audio::Mixer::kMaxChannelVolume, 0, false);
+ } else {
+ // We need to make an inputstream for the getMusicTimer() function (otherwise some scenes like the intro will hang).
+ // Specifying an id makes sure there is always just one active
+ _signal = 0;
+ _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, new FakeAudioStream(_mixer->getOutputRate()), 1);
+ }
_musicId = nr;
-
- // the Tfmx-player newer "ends" the output by itself, so this should be threadsafe
- if (!_mixer->isSoundHandleActive(_musicHandle))
- _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, &_tfmxMusic, -1, Audio::Mixer::kMaxChannelVolume, 0, false);
}
}