[Scummvm-cvs-logs] SF.net SVN: scummvm: [30628] scummvm/branches/branch-0-11-0
aquadran at users.sourceforge.net
aquadran at users.sourceforge.net
Thu Jan 24 00:43:07 CET 2008
Revision: 30628
http://scummvm.svn.sourceforge.net/scummvm/?rev=30628&view=rev
Author: aquadran
Date: 2008-01-23 15:43:06 -0800 (Wed, 23 Jan 2008)
Log Message:
-----------
backport fixes
Modified Paths:
--------------
scummvm/branches/branch-0-11-0/dists/msvc8/scumm.vcproj
scummvm/branches/branch-0-11-0/dists/msvc9/scumm.vcproj
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.cpp
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.h
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_codecs.cpp
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_music.cpp
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_script.cpp
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.h
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.cpp
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.cpp
scummvm/branches/branch-0-11-0/engines/scumm/scumm.cpp
Added Paths:
-----------
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.h
scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.h
Modified: scummvm/branches/branch-0-11-0/dists/msvc8/scumm.vcproj
===================================================================
--- scummvm/branches/branch-0-11-0/dists/msvc8/scumm.vcproj 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/dists/msvc8/scumm.vcproj 2008-01-23 23:43:06 UTC (rev 30628)
@@ -281,9 +281,17 @@
>
</File>
<File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_tables.h"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.cpp"
>
</File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.h"
+ >
+ </File>
</Filter>
<Filter
Name="insane"
Modified: scummvm/branches/branch-0-11-0/dists/msvc9/scumm.vcproj
===================================================================
--- scummvm/branches/branch-0-11-0/dists/msvc9/scumm.vcproj 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/dists/msvc9/scumm.vcproj 2008-01-23 23:43:06 UTC (rev 30628)
@@ -282,9 +282,17 @@
>
</File>
<File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_tables.h"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.cpp"
>
</File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.h"
+ >
+ </File>
</Filter>
<Filter
Name="insane"
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -32,16 +32,13 @@
#include "scumm/sound.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_track.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
namespace Scumm {
-IMuseDigital::Track::Track()
- : soundId(-1), used(false), stream(NULL), streamSou(NULL) {
-}
-
void IMuseDigital::timer_handler(void *refCon) {
IMuseDigital *imuseDigital = (IMuseDigital *)refCon;
imuseDigital->callback();
@@ -100,6 +97,8 @@
_curMusicCue = 0;
memset(_attributes, 0, sizeof(_attributes));
_nextSeqToPlay = 0;
+ _stopingSequence = 0;
+ _triggerUsed = false;
}
void IMuseDigital::saveOrLoad(Serializer *ser) {
@@ -129,7 +128,7 @@
MKLINE(Track, used, sleByte, VER(31)),
MKLINE(Track, toBeRemoved, sleByte, VER(31)),
MKLINE(Track, souStreamUsed, sleByte, VER(31)),
- MKLINE(Track, mixerStreamRunning, sleByte, VER(31)),
+ MKLINE(Track, mixerStreamRunning, sleByte, VER(31)), // FIXME: OBSOLETE, remove this!
MKLINE(Track, soundPriority, sleInt32, VER(31)),
MKLINE(Track, regionOffset, sleInt32, VER(31)),
MK_OBSOLETE(Track, trackOffset, sleInt32, VER(31), VER(31)),
@@ -151,39 +150,35 @@
for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
Track *track = _track[l];
- if (!ser->isSaving()) {
- track->sndDataExtComp = false;
+ if (ser->isLoading()) {
+ memset(track, 0, sizeof(Track));
}
ser->saveLoadEntries(track, trackEntries);
- if (!ser->isSaving()) {
+ if (ser->isLoading()) {
+ _track[l]->trackId = l;
if (!track->used)
continue;
- track->readyToRemove = false;
if ((track->toBeRemoved) || (track->souStreamUsed) || (track->curRegion == -1)) {
- track->streamSou= NULL;
- track->stream = NULL;
track->used = false;
continue;
}
- track->soundDesc = _sound->openSound(track->soundId,
- track->soundName, track->soundType,
- track->volGroupId, -1);
+ // TODO: The code below has a lot in common with that in IMuseDigital::startSound.
+ // Try to refactor them to reduce the code duplication.
+
+ track->soundDesc = _sound->openSound(track->soundId, track->soundName, track->soundType, track->volGroupId, -1);
+ if (!track->soundDesc)
+ track->soundDesc = _sound->openSound(track->soundId, track->soundName, track->soundType, track->volGroupId, 1);
+ if (!track->soundDesc)
+ track->soundDesc = _sound->openSound(track->soundId, track->soundName, track->soundType, track->volGroupId, 2);
+
if (!track->soundDesc) {
- warning("IMuseDigital::saveOrLoad: Can't open sound so will not be resumed, propably on diffrent CD");
- track->streamSou = NULL;
- track->stream = NULL;
+ warning("IMuseDigital::saveOrLoad: Can't open sound so will not be resumed");
track->used = false;
continue;
}
- if (track->sndDataExtComp) {
- track->regionOffset = 0;
- }
track->sndDataExtComp = _sound->isSndDataExtComp(track->soundDesc);
- if (track->sndDataExtComp) {
- track->regionOffset = 0;
- }
track->dataOffset = _sound->getRegionOffset(track->soundDesc, track->curRegion);
int bits = _sound->getBits(track->soundDesc);
int channels = _sound->getChannels(track->soundDesc);
@@ -206,21 +201,9 @@
track->mixerFlags |= kFlagLittleEndian;
#endif
- track->streamSou = NULL;
track->stream = Audio::makeAppendableAudioStream(freq, makeMixerFlags(track->mixerFlags));
- const int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
- const int vol = track->vol / 1000;
- Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
-
- if (track->volGroupId == 1)
- type = Audio::Mixer::kSpeechSoundType;
- if (track->volGroupId == 2)
- type = Audio::Mixer::kSFXSoundType;
- if (track->volGroupId == 3)
- type = Audio::Mixer::kMusicSoundType;
-
- _mixer->playInputStream(type, &track->mixChanHandle, track->stream, -1, vol, pan, false);
+ _mixer->playInputStream(track->getType(), &track->mixChanHandle, track->stream, -1, track->getVol(), track->getPan());
_mixer->pauseHandle(track->mixChanHandle, true);
}
}
@@ -231,9 +214,12 @@
for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
Track *track = _track[l];
- if (track->used && !track->readyToRemove) {
- if (track->toBeRemoved) {
- track->readyToRemove = true;
+ if (track->used) {
+ // Ignore tracks which are about to finish. Also, if it did finish in the meantime,
+ // mark it as unused.
+ if (!track->stream) {
+ if (!_mixer->isSoundHandleActive(track->mixChanHandle))
+ memset(track, 0, sizeof(Track));
continue;
}
@@ -249,7 +235,8 @@
track->volFadeUsed = false;
}
if (track->vol == 0) {
- track->toBeRemoved = true;
+ // Fade out complete -> remove this track
+ flushTrack(track);
continue;
}
}
@@ -265,24 +252,14 @@
debug(5, "Fade: sound(%d), Vol(%d)", track->soundId, track->vol / 1000);
}
- const int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
- const int vol = track->vol / 1000;
- Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
-
- if (track->volGroupId == 1)
- type = Audio::Mixer::kSpeechSoundType;
- if (track->volGroupId == 2)
- type = Audio::Mixer::kSFXSoundType;
- if (track->volGroupId == 3)
- type = Audio::Mixer::kMusicSoundType;
-
- if (track->stream) {
+ if (!track->souStreamUsed) {
+ assert(track->stream);
byte *tmpSndBufferPtr = NULL;
int32 curFeedSize = 0;
if (track->curRegion == -1) {
switchToNextRegion(track);
- if (track->toBeRemoved)
+ if (!track->stream) // Seems we reached the end of the stream
continue;
}
@@ -321,7 +298,7 @@
int tmpFeedSize = _sound->getDataFromRegion(track->soundDesc, track->curRegion, &tmpPtr, tmpOffset, tmpFeedSize12Bits);
curFeedSize = BundleCodecs::decode12BitsSample(tmpPtr, &tmpSndBufferPtr, tmpFeedSize);
- free(tmpPtr);
+ delete[] tmpPtr;
} else if (bits == 16) {
curFeedSize = _sound->getDataFromRegion(track->soundDesc, track->curRegion, &tmpSndBufferPtr, track->regionOffset, feedSize);
if (channels == 1) {
@@ -341,8 +318,6 @@
curFeedSize = feedSize;
if (_mixer->isReady()) {
- _mixer->setChannelVolume(track->mixChanHandle, vol);
- _mixer->setChannelBalance(track->mixChanHandle, pan);
track->stream->queueBuffer(tmpSndBufferPtr, curFeedSize);
track->regionOffset += curFeedSize;
} else
@@ -350,87 +325,92 @@
if (_sound->isEndOfRegion(track->soundDesc, track->curRegion)) {
switchToNextRegion(track);
- if (track->toBeRemoved)
+ if (!track->stream) // Seems we reached the end of the stream
break;
}
feedSize -= curFeedSize;
assert(feedSize >= 0);
} while (feedSize != 0);
- } else if (track->streamSou) {
- if (_mixer->isReady()) {
- if (!track->mixerStreamRunning) {
- track->mixerStreamRunning = true;
- _mixer->playInputStream(type, &track->mixChanHandle, track->streamSou, -1, vol, pan, false);
- } else {
- _mixer->setChannelVolume(track->mixChanHandle, vol);
- _mixer->setChannelBalance(track->mixChanHandle, pan);
- }
- }
}
+ if (_mixer->isReady()) {
+ _mixer->setChannelVolume(track->mixChanHandle, track->getVol());
+ _mixer->setChannelBalance(track->mixChanHandle, track->getPan());
+ }
}
}
}
void IMuseDigital::switchToNextRegion(Track *track) {
assert(track);
- debug(5, "switchToNextRegion(track:%d)", track->trackId);
if (track->trackId >= MAX_DIGITAL_TRACKS) {
- track->toBeRemoved = true;
- debug(5, "exit (fadetrack can't go next region) switchToNextRegion(trackId:%d)", track->trackId);
+ flushTrack(track);
+ debug(5, "SwToNeReg(trackId:%d) - fadetrack can't go next region, exiting SwToNeReg", track->trackId);
return;
}
int num_regions = _sound->getNumRegions(track->soundDesc);
if (++track->curRegion == num_regions) {
- track->toBeRemoved = true;
- debug(5, "exit (end of regions) switchToNextRegion(track:%d)", track->trackId);
+ flushTrack(track);
+ debug(5, "SwToNeReg(trackId:%d) - end of region, exiting SwToNeReg", track->trackId);
return;
}
ImuseDigiSndMgr::SoundDesc *soundDesc = track->soundDesc;
+ if (_triggerUsed && track->soundDesc->numMarkers) {
+ if (_sound->checkForTriggerByRegionAndMarker(soundDesc, track->curRegion, _triggerParams.marker)) {
+ debug(5, "SwToNeReg(trackId:%d) - trigger %s reached", track->trackId, _triggerParams.marker);
+ debug(5, "SwToNeReg(trackId:%d) - exit current region %d", track->trackId, track->curRegion);
+ debug(5, "SwToNeReg(trackId:%d) - call cloneToFadeOutTrack(delay:%d)", track->trackId, _triggerParams.fadeOutDelay);
+ Track *fadeTrack = cloneToFadeOutTrack(track, _triggerParams.fadeOutDelay);
+ if (fadeTrack) {
+ fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundDesc, fadeTrack->curRegion);
+ fadeTrack->regionOffset = 0;
+ debug(5, "SwToNeReg(trackId:%d)-sound(%d) select region %d, curHookId: %d", fadeTrack->trackId, fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
+ fadeTrack->curHookId = 0;
+ }
+ flushTrack(track);
+ startMusic(_triggerParams.filename, _triggerParams.soundId, _triggerParams.hookId, _triggerParams.volume);
+ _triggerUsed = false;
+ return;
+ }
+ }
+
int jumpId = _sound->getJumpIdByRegionAndHookId(soundDesc, track->curRegion, track->curHookId);
- if (jumpId == -1)
- jumpId = _sound->getJumpIdByRegionAndHookId(soundDesc, track->curRegion, 0);
if (jumpId != -1) {
int region = _sound->getRegionIdByJumpId(soundDesc, jumpId);
assert(region != -1);
int sampleHookId = _sound->getJumpHookId(soundDesc, jumpId);
assert(sampleHookId != -1);
- int fadeDelay = (60 * _sound->getJumpFade(soundDesc, jumpId)) / 1000;
- if (sampleHookId != 0) {
- if (track->curHookId == sampleHookId) {
- if (fadeDelay != 0) {
- Track *fadeTrack = cloneToFadeOutTrack(track, fadeDelay);
- if (fadeTrack) {
- fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundDesc, fadeTrack->curRegion);
- fadeTrack->regionOffset = 0;
- debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
- fadeTrack->curHookId = 0;
- }
- }
- track->curRegion = region;
- debug(5, "switchToNextRegion-sound(%d) jump to region %d, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
- track->curHookId = 0;
- }
- } else {
- if (fadeDelay != 0) {
+ debug(5, "SwToNeReg(trackId:%d) - JUMP found - sound:%d, track hookId:%d, data hookId:%d", track->trackId, track->soundId, track->curHookId, sampleHookId);
+ if (track->curHookId == sampleHookId) {
+ int fadeDelay = (60 * _sound->getJumpFade(soundDesc, jumpId)) / 1000;
+ debug(5, "SwToNeReg(trackId:%d) - sound(%d) match hookId", track->trackId, track->soundId);
+ if (fadeDelay) {
+ debug(5, "SwToNeReg(trackId:%d) - call cloneToFadeOutTrack(delay:%d)", track->trackId, fadeDelay);
Track *fadeTrack = cloneToFadeOutTrack(track, fadeDelay);
if (fadeTrack) {
fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundDesc, fadeTrack->curRegion);
fadeTrack->regionOffset = 0;
- debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
+ debug(5, "SwToNeReg(trackId:%d) - sound(%d) faded track, select region %d, curHookId: %d", fadeTrack->trackId, fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
+ fadeTrack->curHookId = 0;
}
}
track->curRegion = region;
- debug(5, "switchToNextRegion-sound(%d) jump to region %d, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
+ debug(5, "SwToNeReg(trackId:%d) - sound(%d) jump to region %d, curHookId: %d", track->trackId, track->soundId, track->curRegion, track->curHookId);
+ track->curHookId = 0;
+ } else {
+ debug(5, "SwToNeReg(trackId:%d) - Normal switch region, sound(%d), hookId(%d)", track->trackId, track->soundId, track->curHookId);
}
+ } else {
+ debug(5, "SwToNeReg(trackId:%d) - Normal switch region, sound(%d), hookId(%d)", track->trackId, track->soundId, track->curHookId);
}
- debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
+ debug(5, "SwToNeReg(trackId:%d) - sound(%d), select region %d", track->trackId, track->soundId, track->curRegion);
track->dataOffset = _sound->getRegionOffset(soundDesc, track->curRegion);
track->regionOffset = 0;
+ debug(5, "SwToNeReg(trackId:%d) - end of func", track->trackId);
}
} // End of namespace Scumm
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.h
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.h 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse.h 2008-01-23 23:43:06 UTC (rev 30628)
@@ -39,73 +39,34 @@
namespace Scumm {
-#define MAX_DIGITAL_TRACKS 8
-#define MAX_DIGITAL_FADETRACKS 8
+enum {
+ MAX_DIGITAL_TRACKS = 8,
+ MAX_DIGITAL_FADETRACKS = 8
+};
struct imuseDigTable;
struct imuseComiTable;
class Serializer;
class ScummEngine_v7;
+struct Track;
-// These flag bits correspond exactly to the sound mixer flags of March 2007.
-// We don't want to use the mixer flags directly, because then our saved games
-// will break in interesting ways if the mixer flags are ever assigned new
-// values. Now they should keep working, as long as these flags don't change.
-
-enum {
- kFlagUnsigned = 1 << 0,
- kFlag16Bits = 1 << 1,
- kFlagLittleEndian = 1 << 2,
- kFlagStereo = 1 << 3,
- kFlagReverseStereo = 1 << 4
-
- // Not used by Digital iMUSE
- // kFlagAutoFree = 1 << 5,
- // kFlagLoop = 1 << 6
-};
-
class IMuseDigital : public MusicEngine {
private:
int _callbackFps; // value how many times callback needs to be called per second
- struct Track {
- int trackId; // used to identify track by value (0-15)
-
- int8 pan; // panning value of sound
- int32 vol; // volume level (values 0-127 * 1000)
- int32 volFadeDest; // volume level which fading target (values 0-127 * 1000)
- int32 volFadeStep; // delta of step while changing volume at each imuse callback
- int32 volFadeDelay; // time in ms how long fading volume must be
- bool volFadeUsed; // flag if fading is in progress
-
- int32 soundId; // sound id used by scumm script
- char soundName[15]; // sound name but also filename of sound in bundle data
- bool used; // flag mean that track is used
- bool toBeRemoved; // flag mean that track need to be free
- bool readyToRemove; // flag mean that track is ready to stop
- bool mixerStreamRunning; // flag mean sound mixer's stream is running
- bool souStreamUsed; // flag mean that track use stream from sou file
- bool sndDataExtComp;// flag mean that sound data is compressed by scummvm tools
- int32 soundPriority;// priority level of played sound (0-127)
- int32 regionOffset; // offset to sound data relative to begining of current region
- int32 dataOffset; // offset to sound data relative to begining of 'DATA' chunk
- int32 curRegion; // id of current used region
- int32 curHookId; // id of current used hook id
- int32 volGroupId; // id of volume group (IMUSE_VOLGRP_VOICE, IMUSE_VOLGRP_SFX, IMUSE_VOLGRP_MUSIC)
- int32 soundType; // type of sound data (kSpeechSoundType, kSFXSoundType, kMusicSoundType)
- int32 feedSize; // size of sound data needed to be filled at each callback iteration
- int32 dataMod12Bit; // value used between all callback to align 12 bit source of data
- int32 mixerFlags; // flags for sound mixer's channel (kFlagStereo, kFlag16Bits, kFlagReverseStereo, kFlagUnsigned, kFlagLittleEndian)
-
- ImuseDigiSndMgr::SoundDesc *soundDesc; // sound handle used by iMuse sound manager
- Audio::SoundHandle mixChanHandle; // sound mixer's channel handle
- Audio::AppendableAudioStream *stream; // sound mixer's audio stream handle for *.la1 and *.bun
- Audio::AudioStream *streamSou; // sound mixer's audio stream handle for *.sou
-
- Track();
+ struct TriggerParams {
+ char marker[10];
+ int fadeOutDelay;
+ char filename[13];
+ int soundId;
+ int hookId;
+ int volume;
};
+ TriggerParams _triggerParams;
+ bool _triggerUsed;
+
Track *_track[MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS];
Common::Mutex _mutex;
@@ -118,18 +79,19 @@
bool _pause; // flag mean that iMuse callback should be idle
- int32 _attributes[188]; // internal atributes for each music file to store and check later
+ int32 _attributes[188]; // internal attributes for each music file to store and check later
int32 _nextSeqToPlay; // id of sequence type of music needed played
int32 _curMusicState; // current or previous id of music
int32 _curMusicSeq; // current or previous id of sequence music
int32 _curMusicCue; // current cue for current music. used in FT
+ int _stopingSequence;
int32 makeMixerFlags(int32 flags);
static void timer_handler(void *refConf);
void callback();
void switchToNextRegion(Track *track);
int allocSlot(int priority);
- void startSound(int soundId, const char *soundName, int soundType, int volGroupId, Audio::AudioStream *input, int hookId, int volume, int priority);
+ void startSound(int soundId, const char *soundName, int soundType, int volGroupId, Audio::AudioStream *input, int hookId, int volume, int priority, Track *otherTrack);
void selectVolumeGroup(int soundId, int volGroupId);
int32 getPosInMs(int soundId);
@@ -137,6 +99,9 @@
int getSoundIdByName(const char *soundName);
void fadeOutMusic(int fadeDelay);
+ void fadeOutMusicAndStartNew(int fadeDelay, const char *filename, int soundId);
+ void setTrigger(TriggerParams *trigger);
+ void setHookIdForMusic(int hookId);
Track *cloneToFadeOutTrack(Track *track, int fadeDelay);
void setFtMusicState(int stateId);
@@ -146,12 +111,14 @@
void setComiMusicState(int stateId);
void setComiMusicSequence(int seqId);
- void playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence);
+ void playComiMusic(const char *songName, const imuseComiTable *table, int attribPos, bool sequence);
void setDigMusicState(int stateId);
void setDigMusicSequence(int seqId);
- void playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence);
+ void playDigMusic(const char *songName, const imuseDigTable *table, int attribPos, bool sequence);
+ void flushTrack(Track *track);
+
public:
IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer, int fps);
virtual ~IMuseDigital();
@@ -162,6 +129,7 @@
void startVoice(int soundId, const char *soundName);
void startMusic(int soundId, int volume);
void startMusic(const char *soundName, int soundId, int hookId, int volume);
+ void startMusicWithOtherPos(const char *soundName, int soundId, int hookId, int volume, Track *otherTrack);
void startSfx(int soundId, int priority);
void startSound(int sound)
{ error("IMuseDigital::startSound(int) should be never called"); }
@@ -174,7 +142,6 @@
void setPan(int soundId, int pan);
void setFade(int soundId, int destVolume, int delay60HzTicks);
int getCurMusicSoundId();
- char *getCurMusicSoundName();
void setHookId(int soundId, int hookId);
void setMusicVolume(int vol) {}
void stopSound(int sound);
@@ -191,61 +158,6 @@
int32 getCurMusicLipSyncHeight(int syncId);
};
-struct imuseRoomMap {
- int8 roomId;
- byte stateIndex1;
- byte offset;
- byte stateIndex2;
- byte atribPos;
- byte stateIndex3;
-};
-
-struct imuseDigTable {
- byte transitionType;
- int16 soundId;
- char name[20];
- byte atribPos;
- byte hookId;
- char filename[13];
-};
-
-struct imuseComiTable {
- byte transitionType;
- int16 soundId;
- char name[20];
- byte atribPos;
- byte hookId;
- int16 fadeOutDelay;
- char filename[13];
-};
-
-
-struct imuseFtNames {
- char name[20];
-};
-
-struct imuseFtStateTable {
- char audioName[9];
- byte transitionType;
- byte volume;
- char name[21];
-};
-
-struct imuseFtSeqTable {
- char audioName[9];
- byte transitionType;
- byte volume;
-};
-
-extern const imuseRoomMap _digStateMusicMap[];
-extern const imuseDigTable _digStateMusicTable[];
-extern const imuseDigTable _digSeqMusicTable[];
-extern const imuseComiTable _comiStateMusicTable[];
-extern const imuseComiTable _comiSeqMusicTable[];
-extern const imuseFtStateTable _ftStateMusicTable[];
-extern const imuseFtSeqTable _ftSeqMusicTable[];
-extern const imuseFtNames _ftSeqNames[];
-
} // End of namespace Scumm
#endif
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_bndmgr.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_bndmgr.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -281,7 +281,7 @@
lastBlock = _numCompItems - 1;
int32 blocksFinalSize = 0x2000 * (1 + lastBlock - firstBlock);
- *compFinal = (byte *)malloc(blocksFinalSize);
+ *compFinal = new byte[blocksFinalSize];
assert(*compFinal);
finalSize = 0;
@@ -348,7 +348,7 @@
return final_size;
}
- debug(2, "BundleMgr::decompressSampleByName() Failed finding voice %s", name);
+ debug(2, "BundleMgr::decompressSampleByName() Failed finding sound %s", name);
return final_size;
}
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_codecs.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_codecs.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_codecs.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -34,7 +34,7 @@
uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size) {
uint32 loop_size = size / 3;
uint32 s_size = loop_size * 4;
- byte *ptr = *dst = (byte *)malloc(s_size);
+ byte *ptr = *dst = new byte[s_size];
assert(ptr);
uint32 tmp;
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_music.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_music.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_music.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "scumm/scumm.h"
#include "scumm/imuse_digi/dimuse.h"
+#include "scumm/imuse_digi/dimuse_tables.h"
namespace Scumm {
@@ -54,7 +55,7 @@
int offset = _attributes[_digStateMusicMap[num].offset];
if (offset == 0) {
- if (_attributes[_digStateMusicMap[num].atribPos] != 0) {
+ if (_attributes[_digStateMusicMap[num].attribPos] != 0) {
num = _digStateMusicMap[num].stateIndex3;
} else {
num = _digStateMusicMap[num].stateIndex1;
@@ -112,12 +113,12 @@
} else {
playDigMusic(_digSeqMusicTable[num].name, &_digSeqMusicTable[num], 0, true);
_nextSeqToPlay = 0;
- _attributes[DIG_SEQ_OFFSET + num] = 1;
+ _attributes[DIG_SEQ_OFFSET + num] = 1; // _attributes[COMI_SEQ_OFFSET] in Comi are not used as it doesn't have 'room' attributes table
}
} else {
if (_nextSeqToPlay != 0) {
playDigMusic(_digSeqMusicTable[_nextSeqToPlay].name, &_digSeqMusicTable[_nextSeqToPlay], 0, true);
- _attributes[DIG_SEQ_OFFSET + _nextSeqToPlay] = 1;
+ _attributes[DIG_SEQ_OFFSET + _nextSeqToPlay] = 1; // _attributes[COMI_SEQ_OFFSET] in Comi are not used as it doesn't have 'room' attributes table
num = _nextSeqToPlay;
_nextSeqToPlay = 0;
} else {
@@ -132,74 +133,76 @@
_curMusicSeq = num;
}
-void IMuseDigital::playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence) {
+void IMuseDigital::playDigMusic(const char *songName, const imuseDigTable *table, int attribPos, bool sequence) {
int hookId = 0;
if (songName != NULL) {
if ((_attributes[DIG_SEQ_OFFSET + 38]) && (!_attributes[DIG_SEQ_OFFSET + 41])) {
- if ((atribPos == 43) || (atribPos == 44))
+ if ((attribPos == 43) || (attribPos == 44))
hookId = 3;
}
if ((_attributes[DIG_SEQ_OFFSET + 46] != 0) && (_attributes[DIG_SEQ_OFFSET + 48] == 0)) {
- if ((atribPos == 38) || (atribPos == 39))
+ if ((attribPos == 38) || (attribPos == 39))
hookId = 3;
}
if ((_attributes[DIG_SEQ_OFFSET + 53] != 0)) {
- if ((atribPos == 50) || (atribPos == 51))
+ if ((attribPos == 50) || (attribPos == 51))
hookId = 3;
}
- if ((atribPos != 0) && (hookId == 0)) {
- if (table->atribPos != 0)
- atribPos = table->atribPos;
- hookId = _attributes[DIG_STATE_OFFSET + atribPos];
+ if ((attribPos != 0) && (hookId == 0)) {
+ if (table->attribPos != 0)
+ attribPos = table->attribPos;
+ hookId = _attributes[DIG_STATE_OFFSET + attribPos];
if (table->hookId != 0) {
if ((hookId != 0) && (table->hookId > 1)) {
- _attributes[DIG_STATE_OFFSET + atribPos] = 2;
+ _attributes[DIG_STATE_OFFSET + attribPos] = 2;
} else {
- _attributes[DIG_STATE_OFFSET + atribPos] = hookId + 1;
+ _attributes[DIG_STATE_OFFSET + attribPos] = hookId + 1;
if (table->hookId < hookId + 1)
- _attributes[DIG_STATE_OFFSET + atribPos] = 1;
+ _attributes[DIG_STATE_OFFSET + attribPos] = 1;
}
}
}
}
- fadeOutMusic(120);
+ if (!songName) {
+ fadeOutMusic(120);
+ return;
+ }
switch (table->transitionType) {
- case 0:
- case 5:
- case 6:
- break;
- case 3:
- case 4:
- if (table->filename[0] == 0) {
- return;
- }
- if ((!sequence) && (table->atribPos != 0) &&
- (table->atribPos == _digStateMusicTable[_curMusicState].atribPos)) {
- startMusic(table->filename, table->soundId, 0, 127);
- return;
- }
+ case 0:
+ case 5:
+ break;
+ case 3:
+ case 4:
+ if (table->filename[0] == 0) {
+ fadeOutMusic(60);
+ return;
+ }
+ if (table->transitionType == 4)
+ _stopingSequence = 1;
+ if ((!sequence) && (table->attribPos != 0) &&
+ (table->attribPos == _digStateMusicTable[_curMusicState].attribPos)) {
+ fadeOutMusicAndStartNew(108, table->filename, table->soundId);
+ } else {
+ fadeOutMusic(108);
startMusic(table->filename, table->soundId, hookId, 127);
- break;
+ }
+ break;
+ case 6:
+ _stopingSequence = 1;
+ break;
}
}
void IMuseDigital::setComiMusicState(int stateId) {
int l, num = -1;
- // This happens at the beginning of Part II, but should apparently not
- // do anything since the correct music is already playing. A left-over
- // of some kind?
-
- if (stateId == 4)
- return;
-
- if (stateId == 0)
+ if (stateId == 0 || stateId == 4)
stateId = 1000;
for (l = 0; _comiStateMusicTable[l].soundId != -1; l++) {
@@ -209,8 +212,10 @@
break;
}
}
- assert(num != -1);
+ if (num == -1)
+ return;
+
if (_curMusicState == num)
return;
@@ -237,14 +242,18 @@
break;
}
}
- assert(num != -1);
+ if (num == -1)
+ return;
+
if (_curMusicSeq == num)
return;
if (num != 0) {
- if (_curMusicSeq && ((_comiSeqMusicTable[_curMusicSeq].transitionType == 4) || (_comiSeqMusicTable[_curMusicSeq].transitionType == 6))) {
+ if (_curMusicSeq && ((_comiSeqMusicTable[_curMusicSeq].transitionType == 4)
+ || (_comiSeqMusicTable[_curMusicSeq].transitionType == 6))) {
_nextSeqToPlay = num;
+ return;
} else {
playComiMusic(_comiSeqMusicTable[num].name, &_comiSeqMusicTable[num], 0, true);
_nextSeqToPlay = 0;
@@ -266,68 +275,70 @@
_curMusicSeq = num;
}
-void IMuseDigital::playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence) {
+void IMuseDigital::playComiMusic(const char *songName, const imuseComiTable *table, int attribPos, bool sequence) {
int hookId = 0;
- if ((songName != NULL) && (atribPos != 0)) {
- if (table->atribPos != 0)
- atribPos = table->atribPos;
- hookId = _attributes[COMI_STATE_OFFSET + atribPos];
+ if ((songName != NULL) && (attribPos != 0)) {
+ if (table->attribPos != 0)
+ attribPos = table->attribPos;
+ hookId = _attributes[COMI_STATE_OFFSET + attribPos];
if (table->hookId != 0) {
if ((hookId != 0) && (table->hookId > 1)) {
- _attributes[COMI_STATE_OFFSET + atribPos] = 2;
+ _attributes[COMI_STATE_OFFSET + attribPos] = 2;
} else {
- _attributes[COMI_STATE_OFFSET + atribPos] = hookId + 1;
+ _attributes[COMI_STATE_OFFSET + attribPos] = hookId + 1;
if (table->hookId < hookId + 1)
- _attributes[COMI_STATE_OFFSET + atribPos] = 1;
+ _attributes[COMI_STATE_OFFSET + attribPos] = 1;
}
}
}
+ if (!songName) {
+ fadeOutMusic(120);
+ return;
+ }
+
switch (table->transitionType) {
- case 0:
- fadeOutMusic(120);
- break;
- case 8:
- case 9:
- setHookId(table->soundId, table->soundId);
- break;
- case 1:
- if (table->filename[0] == 0) {
- fadeOutMusic(120);
- return;
- }
- fadeOutMusic(120);
- startMusic(table->filename, table->soundId, 0, 1);
- setFade(table->soundId, 127, 120);
- break;
- case 2:
- if (table->filename[0] == 0) {
- fadeOutMusic(60);
- return;
- }
+ case 0:
+ break;
+ case 8:
+ setHookIdForMusic(table->hookId);
+ break;
+ case 9:
+ _stopingSequence = 1;
+ setHookIdForMusic(table->hookId);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 12:
+ if (table->filename[0] == 0) {
+ fadeOutMusic(60);
+ return;
+ }
+ if (getCurMusicSoundId() == table->soundId)
+ return;
+ if (table->transitionType == 4)
+ _stopingSequence = 1;
+ if (table->transitionType == 2) {
fadeOutMusic(table->fadeOutDelay);
startMusic(table->filename, table->soundId, table->hookId, 127);
- break;
- case 3:
- case 4:
- case 12:
- if (table->filename[0] == 0) {
- fadeOutMusic(60);
- return;
- }
+ return;
+ }
+ if ((!sequence) && (table->attribPos != 0) &&
+ (table->attribPos == _comiStateMusicTable[_curMusicState].attribPos)) {
+ fadeOutMusicAndStartNew(table->fadeOutDelay, table->filename, table->soundId);
+ } else if (table->transitionType == 12) {
+ TriggerParams trigger;
+ strcpy(trigger.marker, "exit"); trigger.fadeOutDelay = table->fadeOutDelay;
+ strcpy(trigger.filename, table->filename); trigger.soundId = table->soundId;
+ trigger.hookId = table->hookId; trigger.volume = 127;
+ setTrigger(&trigger);
+ } else {
fadeOutMusic(table->fadeOutDelay);
- if ((!sequence) && (table->atribPos != 0) &&
- (table->atribPos == _comiStateMusicTable[_curMusicState].atribPos)) {
- startMusic(table->filename, table->soundId, 0, 127);
- return;
- }
- if (table->transitionType == 12) {
- startMusic(table->filename, table->soundId, table->hookId, 127);
- } else {
- startMusic(table->filename, table->soundId, hookId, 127);
- }
- break;
+ startMusic(table->filename, table->soundId, hookId, 127);
+ }
+ break;
}
}
@@ -418,19 +429,19 @@
fadeOutMusic(200);
switch (opcode) {
- case 0:
- case 4:
- break;
- case 1:
- case 2:
- case 3:
- {
- int soundId = getSoundIdByName(songName);
- if (soundId != -1) {
- startMusic(soundId, volume);
- }
+ case 0:
+ case 4:
+ break;
+ case 1:
+ case 2:
+ case 3:
+ {
+ int soundId = getSoundIdByName(songName);
+ if (soundId != -1) {
+ startMusic(soundId, volume);
}
- break;
+ }
+ break;
}
}
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_script.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_script.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_script.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -31,6 +31,7 @@
#include "scumm/sound.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_track.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
@@ -83,10 +84,10 @@
}
break;
case 25: // ImuseStartStream
- debug(5, "ImuseStartStream (%d, %d, %d)", soundId, c, d);
+ debug(3, "ImuseStartStream (%d, %d, %d)", soundId, c, d);
break;
case 26: // ImuseSwitchStream
- debug(5, "ImuseSwitchStream (%d, %d, %d, %d, %d)", soundId, c, d, e, f);
+ debug(3, "ImuseSwitchStream (%d, %d, %d, %d, %d)", soundId, c, d, e, f);
break;
case 0x1000: // ImuseSetState
debug(5, "ImuseSetState (%d)", b);
@@ -101,19 +102,23 @@
}
}
} else if ((_vm->_game.id == GID_CMI) && (_vm->_game.features & GF_DEMO)) {
- fadeOutMusic(120);
if (b == 2) {
+ fadeOutMusic(108);
startMusic("in1.imx", 1100, 0, 127);
} else if (b == 4) {
+ fadeOutMusic(108);
startMusic("in2.imx", 1120, 0, 127);
} else if (b == 8) {
+ fadeOutMusic(108);
startMusic("out1.imx", 1140, 0, 127);
} else if (b == 9) {
+ fadeOutMusic(108);
startMusic("out2.imx", 1150, 0, 127);
} else if (b == 16) {
+ fadeOutMusic(108);
startMusic("gun.imx", 1210, 0, 127);
} else {
- warning("imuse digital: set state unknown for cmi demo: %d, room: %d", b, _vm->_currentRoom);
+ fadeOutMusic(120);
}
} else if (_vm->_game.id == GID_DIG) {
setDigMusicState(b);
@@ -163,39 +168,55 @@
}
}
+void IMuseDigital::flushTrack(Track *track) {
+ track->toBeRemoved = true;
+
+ if (track->souStreamUsed) {
+ _mixer->stopHandle(track->mixChanHandle);
+ } else if (track->stream) {
+ debug(5, "flushTrack() - soundId:%d", track->soundId);
+ // Finalize the appendable stream, then remove our reference to it.
+ // Note that there might still be some data left in the buffers of the
+ // appendable stream. We play it nice and wait till all of it
+ // played. The audio mixer will take care of it afterwards (and dispose it).
+ track->stream->finish();
+ track->stream = 0;
+ if (track->soundDesc) {
+ _sound->closeSound(track->soundDesc);
+ track->soundDesc = 0;
+ }
+ }
+
+ if (!_mixer->isSoundHandleActive(track->mixChanHandle)) {
+ memset(track, 0, sizeof(Track));
+ }
+}
+
void IMuseDigital::flushTracks() {
Common::StackLock lock(_mutex, "IMuseDigital::flushTracks()");
- debug(5, "flushTracks()");
+ debug(6, "flushTracks()");
for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
Track *track = _track[l];
- if (track->used && track->readyToRemove) {
- if (track->stream) {
- // Finalize the appendable stream
- track->stream->finish();
- // There might still be some data left in the buffers of the
- // appendable stream. We play it nice and wait till all of it
- // played.
- if (track->stream->endOfStream()) {
- _mixer->stopHandle(track->mixChanHandle);
- delete track->stream;
- track->stream = NULL;
- _sound->closeSound(track->soundDesc);
- track->soundDesc = NULL;
- track->used = false;
- }
- } else if (track->streamSou) {
- _mixer->stopHandle(track->mixChanHandle);
- delete track->streamSou;
- track->streamSou = NULL;
- track->used = false;
- }
+ if (track->used && track->toBeRemoved && !_mixer->isSoundHandleActive(track->mixChanHandle)) {
+ debug(5, "flushTracks() - soundId:%d", track->soundId);
+ memset(track, 0, sizeof(Track));
}
}
}
void IMuseDigital::refreshScripts() {
Common::StackLock lock(_mutex, "IMuseDigital::refreshScripts()");
- debug(5, "refreshScripts()");
+ debug(6, "refreshScripts()");
+
+ if (_stopingSequence) {
+ // small delay, it seems help for fix bug #1757010
+ if (_stopingSequence++ > 120) {
+ debug(5, "refreshScripts() Force restore music state");
+ parseScriptCmds(0x1001, 0, 0, 0, 0, 0, 0, 0);
+ _stopingSequence = 0;
+ }
+ }
+
bool found = false;
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
@@ -204,35 +225,40 @@
}
}
- if (!found && (_curMusicSeq != 0)) {
- debug(5, "refreshScripts() Start Sequence");
+ if (!found && _curMusicState) {
+ debug(5, "refreshScripts() Restore music state");
parseScriptCmds(0x1001, 0, 0, 0, 0, 0, 0, 0);
}
}
void IMuseDigital::startVoice(int soundId, Audio::AudioStream *input) {
debug(5, "startVoiceStream(%d)", soundId);
- startSound(soundId, "", 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127);
+ startSound(soundId, "", 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127, NULL);
}
void IMuseDigital::startVoice(int soundId, const char *soundName) {
- debug(5, "startVoiceBundle(%s)", soundName);
- startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_VOICE, NULL, 0, 127, 127);
+ debug(5, "startVoiceBundle(%s, %d)", soundName, soundId);
+ startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_VOICE, NULL, 0, 127, 127, NULL);
}
void IMuseDigital::startMusic(int soundId, int volume) {
debug(5, "startMusicResource(%d)", soundId);
- startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126);
+ startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126, NULL);
}
void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, int volume) {
- debug(5, "startMusicBundle(%s)", soundName);
- startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_MUSIC, NULL, hookId, volume, 126);
+ debug(5, "startMusicBundle(%s, soundId:%d, hookId:%d)", soundName, soundId, hookId);
+ startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_MUSIC, NULL, hookId, volume, 126, NULL);
}
+void IMuseDigital::startMusicWithOtherPos(const char *soundName, int soundId, int hookId, int volume, Track *otherTrack) {
+ debug(5, "startMusicWithOtherPos(%s, soundId:%d, hookId:%d, oldSoundId:%d)", soundName, soundId, hookId, otherTrack->soundId);
+ startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_MUSIC, NULL, hookId, volume, 126, otherTrack);
+}
+
void IMuseDigital::startSfx(int soundId, int priority) {
debug(5, "startSfx(%d)", soundId);
- startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority);
+ startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority, NULL);
}
void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) {
@@ -244,7 +270,7 @@
Common::StackLock lock(_mutex, "IMuseDigital::getLipSync()");
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
_sound->getSyncSizeAndPtrById(track->soundDesc, syncId, sync_size, &sync_ptr);
if ((sync_size != 0) && (sync_ptr != NULL)) {
sync_size /= 4;
@@ -272,7 +298,7 @@
Common::StackLock lock(_mutex, "IMuseDigital::getPosInMs()");
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
int32 pos = (5 * (track->dataOffset + track->regionOffset)) / (track->feedSize / 200);
return pos;
}
@@ -281,15 +307,16 @@
return 0;
}
-int IMuseDigital::getSoundStatus(int sound) const {
+int IMuseDigital::getSoundStatus(int soundId) const {
Common::StackLock lock(_mutex, "IMuseDigital::getSoundStatus()");
- debug(5, "IMuseDigital::getSoundStatus(%d)", sound);
+ debug(5, "IMuseDigital::getSoundStatus(%d)", soundId);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if (track->soundId == sound) {
- if ((track->streamSou && _mixer->isSoundHandleActive(track->mixChanHandle)) ||
- (track->stream && track->used && !track->readyToRemove)) {
- return 1;
+ // Note: We do not check track->toBeRemoved here on purpose (I *think*, at least).
+ // After all, tracks which are about to stop still are running (if only for a brief time).
+ if ((track->soundId == soundId) && track->used) {
+ if (_mixer->isSoundHandleActive(track->mixChanHandle)) {
+ return 1;
}
}
}
@@ -302,8 +329,9 @@
debug(5, "IMuseDigital::stopSound(%d)", soundId);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->toBeRemoved = true;
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
+ debug(5, "IMuseDigital::stopSound(%d) - stopping sound", soundId);
+ flushTrack(track);
}
}
}
@@ -320,7 +348,7 @@
}
int32 msPos = getPosInMs(soundId);
- debug(5, "IMuseDigital::getCurMusicPosInMs(%d) = %d", soundId, msPos);
+ debug(6, "IMuseDigital::getCurMusicPosInMs(%d) = %d", soundId, msPos);
return msPos;
}
@@ -329,7 +357,7 @@
int32 msPos = getPosInMs(kTalkSoundID) + 50;
int32 width = 0, height = 0;
- debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d)", kTalkSoundID);
+ debug(6, "IMuseDigital::getCurVoiceLipSyncWidth(%d)", kTalkSoundID);
getLipSync(kTalkSoundID, 0, msPos, width, height);
return width;
}
@@ -339,7 +367,7 @@
int32 msPos = getPosInMs(kTalkSoundID) + 50;
int32 width = 0, height = 0;
- debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d)", kTalkSoundID);
+ debug(6, "IMuseDigital::getCurVoiceLipSyncHeight(%d)", kTalkSoundID);
getLipSync(kTalkSoundID, 0, msPos, width, height);
return height;
}
@@ -358,7 +386,7 @@
int32 msPos = getPosInMs(soundId) + 50;
int32 width = 0, height = 0;
- debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d, %d)", soundId, msPos);
+ debug(6, "IMuseDigital::getCurVoiceLipSyncWidth(%d, %d)", soundId, msPos);
getLipSync(soundId, syncId, msPos, width, height);
return width;
}
@@ -377,14 +405,14 @@
int32 msPos = getPosInMs(soundId) + 50;
int32 width = 0, height = 0;
- debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d, %d)", soundId, msPos);
+ debug(6, "IMuseDigital::getCurVoiceLipSyncHeight(%d, %d)", soundId, msPos);
getLipSync(soundId, syncId, msPos, width, height);
return height;
}
void IMuseDigital::stopAllSounds() {
Common::StackLock lock(_mutex, "IMuseDigital::stopAllSounds()");
- debug(0, "IMuseDigital::stopAllSounds");
+ debug(5, "IMuseDigital::stopAllSounds");
for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
Track *track = _track[l];
@@ -392,20 +420,14 @@
// Stop the sound output, *now*. No need to use toBeRemoved etc.
// as we are protected by a mutex, and this method is never called
// from IMuseDigital::callback either.
- if (track->stream) {
- _mixer->stopHandle(track->mixChanHandle);
- delete track->stream;
- track->stream = NULL;
+ _mixer->stopHandle(track->mixChanHandle);
+ if (track->soundDesc) {
+ debug(5, "IMuseDigital::stopAllSounds - stopping sound(%d)", track->soundId);
_sound->closeSound(track->soundDesc);
- track->soundDesc = NULL;
- } else if (track->streamSou) {
- _mixer->stopHandle(track->mixChanHandle);
- delete track->streamSou;
- track->streamSou = NULL;
}
// Mark the track as unused
- track->used = false;
+ memset(track, 0, sizeof(Track));
}
}
}
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -58,19 +58,23 @@
delete _cacheBundleDir;
}
-void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs) {
+void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs, int &numMarkers) {
uint32 tag;
int32 size = 0;
do {
tag = READ_BE_UINT32(ptr); ptr += 4;
switch (tag) {
- case MKID_BE('TEXT'):
case MKID_BE('STOP'):
case MKID_BE('FRMT'):
case MKID_BE('DATA'):
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
+ case MKID_BE('TEXT'):
+ if (!scumm_stricmp((const char *)(ptr + 8), "exit"))
+ numMarkers++;
+ size = READ_BE_UINT32(ptr); ptr += size + 4;
+ break;
case MKID_BE('REGN'):
numRegions++;
size = READ_BE_UINT32(ptr); ptr += size + 4;
@@ -96,8 +100,12 @@
uint32 tag = file->readUint32BE();
assert(tag == MKID_BE('RMAP'));
int32 version = file->readUint32BE();
- if (version != 2) {
- error("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version number, expected 2, but it's: %d.", version);
+ if (version != 3) {
+ if (version == 2) {
+ warning("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version of compressed *.bun file, expected 3, but it's 2.");
+ warning("Suggested to recompress with latest tool from daily builds.");
+ } else
+ error("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version number, expected 3, but it's: %d.", version);
}
sound->bits = file->readUint32BE();
sound->freq = file->readUint32BE();
@@ -105,12 +113,20 @@
sound->numRegions = file->readUint32BE();
sound->numJumps = file->readUint32BE();
sound->numSyncs = file->readUint32BE();
+ if (version >= 3)
+ sound->numMarkers = file->readUint32BE();
+ else
+ sound->numMarkers = 0;
+
sound->region = new Region[sound->numRegions];
assert(sound->region);
sound->jump = new Jump[sound->numJumps];
assert(sound->jump);
sound->sync = new Sync[sound->numSyncs];
assert(sound->sync);
+ sound->marker = new Marker[sound->numMarkers];
+ assert(sound->marker);
+
for (l = 0; l < sound->numRegions; l++) {
sound->region[l].offset = file->readUint32BE();
sound->region[l].length = file->readUint32BE();
@@ -123,9 +139,17 @@
}
for (l = 0; l < sound->numSyncs; l++) {
sound->sync[l].size = file->readUint32BE();
- sound->sync[l].ptr = (byte *)malloc(sound->sync[l].size);
+ sound->sync[l].ptr = new byte[sound->sync[l].size];
file->read(sound->sync[l].ptr, sound->sync[l].size);
}
+ if (version >= 3) {
+ for (l = 0; l < sound->numMarkers; l++) {
+ sound->marker[l].pos = file->readUint32BE();
+ sound->marker[l].length = file->readUint32BE();
+ sound->marker[l].ptr = new char[sound->marker[l].length];
+ file->read(sound->marker[l].ptr, sound->marker[l].length);
+ }
+ }
}
void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
@@ -207,17 +231,21 @@
int curIndexRegion = 0;
int curIndexJump = 0;
int curIndexSync = 0;
+ int curIndexMarker = 0;
sound->numRegions = 0;
sound->numJumps = 0;
sound->numSyncs = 0;
- countElements(ptr, sound->numRegions, sound->numJumps, sound->numSyncs);
+ sound->numMarkers = 0;
+ countElements(ptr, sound->numRegions, sound->numJumps, sound->numSyncs, sound->numMarkers);
sound->region = new Region[sound->numRegions];
assert(sound->region);
sound->jump = new Jump[sound->numJumps];
assert(sound->jump);
sound->sync = new Sync[sound->numSyncs];
assert(sound->sync);
+ sound->marker = new Marker[sound->numMarkers];
+ assert(sound->marker);
do {
tag = READ_BE_UINT32(ptr); ptr += 4;
@@ -229,6 +257,16 @@
sound->channels = READ_BE_UINT32(ptr); ptr += 4;
break;
case MKID_BE('TEXT'):
+ if (!scumm_stricmp((const char *)(ptr + 8), "exit")) {
+ sound->marker[curIndexMarker].pos = READ_BE_UINT32(ptr + 4);
+ sound->marker[curIndexMarker].length = strlen((const char *)(ptr + 8)) + 1;
+ sound->marker[curIndexMarker].ptr = new char[sound->marker[curIndexMarker].length];
+ assert(sound->marker[curIndexMarker].ptr);
+ strcpy(sound->marker[curIndexMarker].ptr, (const char *)(ptr + 8));
+ curIndexMarker++;
+ }
+ size = READ_BE_UINT32(ptr); ptr += size + 4;
+ break;
case MKID_BE('STOP'):
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
@@ -249,7 +287,8 @@
case MKID_BE('SYNC'):
size = READ_BE_UINT32(ptr); ptr += 4;
sound->sync[curIndexSync].size = size;
- sound->sync[curIndexSync].ptr = (byte *)malloc(size);
+ sound->sync[curIndexSync].ptr = new byte[size];
+ assert(sound->sync[curIndexSync].ptr);
memcpy(sound->sync[curIndexSync].ptr, ptr, size);
curIndexSync++;
ptr += size;
@@ -278,7 +317,7 @@
return NULL;
}
-bool ImuseDigiSndMgr::openMusicBundle(SoundDesc *sound, int disk) {
+bool ImuseDigiSndMgr::openMusicBundle(SoundDesc *sound, int &disk) {
bool result = false;
sound->bundle = new BundleMgr(_cacheBundleDir);
@@ -313,7 +352,7 @@
return result;
}
-bool ImuseDigiSndMgr::openVoiceBundle(SoundDesc *sound, int disk) {
+bool ImuseDigiSndMgr::openVoiceBundle(SoundDesc *sound, int &disk) {
bool result = false;
sound->bundle = new BundleMgr(_cacheBundleDir);
@@ -399,7 +438,7 @@
sound->soundId = soundId;
sound->type = soundType;
sound->volGroupId = volGroupId;
- sound->disk = _disk;
+ sound->disk = disk;
return sound;
} else if (soundName[0] == 0) {
if (sound->bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside) == 0 || ptr == NULL) {
@@ -425,7 +464,7 @@
sound->disk = _disk;
prepareSound(ptr, sound);
if ((soundType == IMUSE_BUNDLE) && !sound->compressed) {
- free(ptr);
+ delete[] ptr;
}
return sound;
}
@@ -447,17 +486,26 @@
delete soundDesc->bundle;
for (int r = 0; r < soundDesc->numSyncs; r++)
- free(soundDesc->sync[r].ptr);
+ delete[] soundDesc->sync[r].ptr;
+ for (int r = 0; r < soundDesc->numMarkers; r++)
+ delete[] soundDesc->marker[r].ptr;
delete[] soundDesc->region;
delete[] soundDesc->jump;
delete[] soundDesc->sync;
+ delete[] soundDesc->marker;
memset(soundDesc, 0, sizeof(SoundDesc));
}
ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::cloneSound(SoundDesc *soundDesc) {
+ ImuseDigiSndMgr::SoundDesc *desc;
assert(checkForProperHandle(soundDesc));
- return openSound(soundDesc->soundId, soundDesc->name, soundDesc->type, soundDesc->volGroupId, soundDesc->disk);
+ desc = openSound(soundDesc->soundId, soundDesc->name, soundDesc->type, soundDesc->volGroupId, soundDesc->disk);
+ if (!desc)
+ desc = openSound(soundDesc->soundId, soundDesc->name, soundDesc->type, soundDesc->volGroupId, 1);
+ if (!desc)
+ desc = openSound(soundDesc->soundId, soundDesc->name, soundDesc->type, soundDesc->volGroupId, 2);
+ return desc;
}
bool ImuseDigiSndMgr::checkForProperHandle(SoundDesc *soundDesc) {
@@ -528,6 +576,22 @@
return -1;
}
+bool ImuseDigiSndMgr::checkForTriggerByRegionAndMarker(SoundDesc *soundDesc, int region, const char *marker) {
+ debug(5, "checkForTriggerByRegionAndMarker() region:%d, marker:%s", region, marker);
+ assert(checkForProperHandle(soundDesc));
+ assert(region >= 0 && region < soundDesc->numRegions);
+ assert(marker);
+ int32 offset = soundDesc->region[region].offset;
+ for (int l = 0; l < soundDesc->numMarkers; l++) {
+ if (offset == soundDesc->marker[l].pos) {
+ if (!scumm_stricmp(soundDesc->marker[l].ptr, marker))
+ return true;
+ }
+ }
+
+ return false;
+}
+
void ImuseDigiSndMgr::getSyncSizeAndPtrById(SoundDesc *soundDesc, int number, int32 &sync_size, byte **sync_ptr) {
assert(checkForProperHandle(soundDesc));
assert(number >= 0);
@@ -569,7 +633,7 @@
}
int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte **buf, int32 offset, int32 size) {
- debug(5, "getDataFromRegion() region:%d, offset:%d, size:%d, numRegions:%d", region, offset, size, soundDesc->numRegions);
+ debug(6, "getDataFromRegion() region:%d, offset:%d, size:%d, numRegions:%d", region, offset, size, soundDesc->numRegions);
assert(checkForProperHandle(soundDesc));
assert(buf && offset >= 0 && size >= 0);
assert(region >= 0 && region < soundDesc->numRegions);
@@ -598,6 +662,7 @@
*buf = new byte[size];
assert(*buf);
char fileName[24];
+ int offsetMs = (((offset * 8 * 10) / soundDesc->bits) / (soundDesc->channels * soundDesc->freq)) * 100;
sprintf(fileName, "%s_reg%03d", soundDesc->name, region);
if (scumm_stricmp(fileName, soundDesc->lastFileName) != 0) {
int32 offs = 0, len = 0;
@@ -639,25 +704,26 @@
assert(tmp);
#ifdef USE_FLAC
if (soundMode == 3)
- soundDesc->compressedStream = Audio::makeFlacStream(tmp, true);
+ soundDesc->compressedStream = Audio::makeFlacStream(tmp, true, offsetMs);
#endif
#ifdef USE_VORBIS
if (soundMode == 2)
- soundDesc->compressedStream = Audio::makeVorbisStream(tmp, true);
+ soundDesc->compressedStream = Audio::makeVorbisStream(tmp, true, offsetMs);
#endif
#ifdef USE_MAD
if (soundMode == 1)
- soundDesc->compressedStream = Audio::makeMP3Stream(tmp, true);
+ soundDesc->compressedStream = Audio::makeMP3Stream(tmp, true, offsetMs);
#endif
assert(soundDesc->compressedStream);
}
strcpy(soundDesc->lastFileName, fileName);
}
size = soundDesc->compressedStream->readBuffer((int16 *)*buf, size / 2) * 2;
- if (soundDesc->compressedStream->endOfData()) {
+ if (soundDesc->compressedStream->endOfData() || soundDesc->endFlag) {
delete soundDesc->compressedStream;
soundDesc->compressedStream = NULL;
soundDesc->lastFileName[0] = 0;
+ soundDesc->endFlag = true;
}
}
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.h
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.h 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_sndmgr.h 2008-01-23 23:43:06 UTC (rev 30628)
@@ -65,6 +65,12 @@
byte *ptr; // pointer to sync
};
+ struct Marker {
+ int32 pos; // position Markaer in sound data
+ int32 length; // length of marker string
+ char *ptr; // pointer to string
+ };
+
public:
struct SoundDesc {
@@ -81,6 +87,9 @@
int numSyncs; // number of Syncs
Sync *sync;
+ int numMarkers; // number of Markers
+ Marker *marker;
+
bool endFlag;
bool inUse;
byte *allData;
@@ -110,10 +119,10 @@
byte _disk;
BundleDirCache *_cacheBundleDir;
- bool openMusicBundle(SoundDesc *sound, int disk);
- bool openVoiceBundle(SoundDesc *sound, int disk);
+ bool openMusicBundle(SoundDesc *sound, int &disk);
+ bool openVoiceBundle(SoundDesc *sound, int &disk);
- void countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs);
+ void countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs, int &numMarkers);
public:
@@ -133,6 +142,7 @@
int getNumJumps(SoundDesc *soundDesc);
int getRegionOffset(SoundDesc *soundDesc, int region);
int getJumpIdByRegionAndHookId(SoundDesc *soundDesc, int region, int hookId);
+ bool checkForTriggerByRegionAndMarker(SoundDesc *soundDesc, int region, const char *marker);
int getRegionIdByJumpId(SoundDesc *soundDesc, int jumpId);
int getJumpHookId(SoundDesc *soundDesc, int number);
int getJumpFade(SoundDesc *soundDesc, int number);
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -23,7 +23,8 @@
*/
-#include "scumm/imuse_digi/dimuse.h"
+//#include "scumm/imuse_digi/dimuse.h"
+#include "scumm/imuse_digi/dimuse_tables.h"
namespace Scumm {
Copied: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.h (from rev 30627, scummvm/trunk/engines/scumm/imuse_digi/dimuse_tables.h)
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.h (rev 0)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_tables.h 2008-01-23 23:43:06 UTC (rev 30628)
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#if !defined(SCUMM_IMUSE_DIGI_TABLES_H) && !defined(DISABLE_SCUMM_7_8)
+#define SCUMM_IMUSE_DIGI_TABLES_H
+
+#include "common/scummsys.h"
+
+namespace Scumm {
+
+struct imuseRoomMap {
+ int8 roomId;
+ byte stateIndex1;
+ byte offset;
+ byte stateIndex2;
+ byte attribPos;
+ byte stateIndex3;
+};
+
+struct imuseDigTable {
+ byte transitionType;
+ int16 soundId;
+ char name[20];
+ byte attribPos;
+ byte hookId;
+ char filename[13];
+};
+
+struct imuseComiTable {
+ byte transitionType;
+ int16 soundId;
+ char name[20];
+ byte attribPos;
+ byte hookId;
+ int16 fadeOutDelay;
+ char filename[13];
+};
+
+
+struct imuseFtNames {
+ char name[20];
+};
+
+struct imuseFtStateTable {
+ char audioName[9];
+ byte transitionType;
+ byte volume;
+ char name[21];
+};
+
+struct imuseFtSeqTable {
+ char audioName[9];
+ byte transitionType;
+ byte volume;
+};
+
+extern const imuseRoomMap _digStateMusicMap[];
+extern const imuseDigTable _digStateMusicTable[];
+extern const imuseDigTable _digSeqMusicTable[];
+extern const imuseComiTable _comiStateMusicTable[];
+extern const imuseComiTable _comiSeqMusicTable[];
+extern const imuseFtStateTable _ftStateMusicTable[];
+extern const imuseFtSeqTable _ftSeqMusicTable[];
+extern const imuseFtNames _ftSeqNames[];
+
+} // End of namespace Scumm
+
+#endif
Modified: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -30,6 +30,7 @@
#include "scumm/sound.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_track.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
@@ -52,14 +53,24 @@
for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
if (track->used && !track->toBeRemoved &&
- (lowest_priority > track->soundPriority) && !track->streamSou) {
+ (lowest_priority > track->soundPriority) && !track->souStreamUsed) {
lowest_priority = track->soundPriority;
trackId = l;
}
}
if (lowest_priority <= priority) {
assert(trackId != -1);
- _track[trackId]->toBeRemoved = true;
+ Track *track = _track[trackId];
+
+ // Stop the track immediately
+ _mixer->stopHandle(track->mixChanHandle);
+ if (track->soundDesc) {
+ _sound->closeSound(track->soundDesc);
+ }
+
+ // Mark it as unused
+ memset(track, 0, sizeof(Track));
+
debug(5, "IMuseDigital::allocSlot(): Removed sound %d from track %d", _track[trackId]->soundId, trackId);
} else {
debug(5, "IMuseDigital::allocSlot(): Priority sound too low");
@@ -70,66 +81,47 @@
return trackId;
}
-void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int volGroupId, Audio::AudioStream *input, int hookId, int volume, int priority) {
+void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int volGroupId, Audio::AudioStream *input, int hookId, int volume, int priority, Track *otherTrack) {
Common::StackLock lock(_mutex, "IMuseDigital::startSound()");
- debug(5, "IMuseDigital::startSound(%d)", soundId);
+ debug(5, "IMuseDigital::startSound(%d) - begin func", soundId);
int l = allocSlot(priority);
if (l == -1) {
warning("IMuseDigital::startSound() Can't start sound - no free slots");
return;
}
+ debug(5, "IMuseDigital::startSound(%d, trackId:%d)", soundId, l);
Track *track = _track[l];
- while (1) {
- if (!track->used) {
- break;
- }
- // The designated track is not yet available. So, we call flushTracks()
- // to get it processed (and thus made ready for us). Since the actual
- // processing is done by another thread, we also call parseEvents to
- // give it some time (and to avoid busy waiting/looping).
- flushTracks();
- _mutex.unlock();
-#ifndef __PLAYSTATION2__
- _vm->parseEvents();
-#endif
- _mutex.lock();
- }
+
+ // Reset the track
+ memset(track, 0, sizeof(Track));
track->pan = 64;
track->vol = volume * 1000;
- track->volFadeDest = 0;
- track->volFadeStep = 0;
- track->volFadeDelay = 0;
- track->volFadeUsed = false;
track->soundId = soundId;
- track->mixerStreamRunning = false;
track->volGroupId = volGroupId;
track->curHookId = hookId;
track->soundPriority = priority;
track->curRegion = -1;
- track->dataOffset = 0;
- track->regionOffset = 0;
- track->dataMod12Bit = 0;
- track->mixerFlags = 0;
- track->toBeRemoved = false;
- track->readyToRemove = false;
track->soundType = soundType;
+ track->trackId = l;
int bits = 0, freq = 0, channels = 0;
- if (input) {
- track->feedSize = 0;
- track->souStreamUsed = true;
- track->soundName[0] = 0;
- track->soundDesc = NULL;
+ track->souStreamUsed = (input != 0);
+
+ if (track->souStreamUsed) {
+ _mixer->playInputStream(track->getType(), &track->mixChanHandle, input, -1, track->getVol(), track->getPan());
} else {
- track->souStreamUsed = false;
strcpy(track->soundName, soundName);
track->soundDesc = _sound->openSound(soundId, soundName, soundType, volGroupId, -1);
+ if (!track->soundDesc)
+ track->soundDesc = _sound->openSound(soundId, soundName, soundType, volGroupId, 1);
+ if (!track->soundDesc)
+ track->soundDesc = _sound->openSound(soundId, soundName, soundType, volGroupId, 2);
- if (track->soundDesc == NULL)
+ if (!track->soundDesc)
return;
track->sndDataExtComp = _sound->isSndDataExtComp(track->soundDesc);
@@ -167,28 +159,16 @@
if (track->sndDataExtComp)
track->mixerFlags |= kFlagLittleEndian;
#endif
- }
- if (input) {
- track->streamSou = input;
- track->stream = NULL;
- track->mixerStreamRunning = false;
- } else {
- const int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
- const int vol = track->vol / 1000;
- Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
+ if (otherTrack && otherTrack->used && !otherTrack->toBeRemoved) {
+ track->curRegion = otherTrack->curRegion;
+ track->dataOffset = otherTrack->dataOffset;
+ track->regionOffset = otherTrack->regionOffset;
+ track->dataMod12Bit = otherTrack->dataMod12Bit;
+ }
- if (track->volGroupId == 1)
- type = Audio::Mixer::kSpeechSoundType;
- if (track->volGroupId == 2)
- type = Audio::Mixer::kSFXSoundType;
- if (track->volGroupId == 3)
- type = Audio::Mixer::kMusicSoundType;
-
- track->streamSou = NULL;
track->stream = Audio::makeAppendableAudioStream(freq, makeMixerFlags(track->mixerFlags));
- _mixer->playInputStream(type, &track->mixChanHandle, track->stream, -1, vol, pan, false);
- track->mixerStreamRunning = true;
+ _mixer->playInputStream(track->getType(), &track->mixChanHandle, track->stream, -1, track->getVol(), track->getPan());
}
track->used = true;
@@ -201,7 +181,8 @@
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
+ debug(5, "IMuseDigital::setPriority(%d) - setting", soundId);
track->soundPriority = priority;
}
}
@@ -213,7 +194,8 @@
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
+ debug(5, "IMuseDigital::setVolume(%d) - setting", soundId);
track->vol = volume * 1000;
}
}
@@ -224,7 +206,7 @@
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
track->curHookId = hookId;
}
}
@@ -238,33 +220,21 @@
Track *track = _track[l];
if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
soundId = track->soundId;
+ break;
}
}
return soundId;
}
-char *IMuseDigital::getCurMusicSoundName() {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicSoundName()");
- char *soundName = NULL;
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- soundName = track->soundName;
- }
- }
-
- return soundName;
-}
-
void IMuseDigital::setPan(int soundId, int pan) {
Common::StackLock lock(_mutex, "IMuseDigital::setPan()");
debug(5, "IMuseDigital::setPan(%d, %d)", soundId, pan);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
+ debug(5, "IMuseDigital::setPan(%d) - setting", soundId);
track->pan = pan;
}
}
@@ -280,7 +250,8 @@
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
+ debug(5, "IMuseDigital::setVolumeGroup(%d) - setting", soundId);
track->volGroupId = volGroupId;
}
}
@@ -292,7 +263,8 @@
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
+ if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
+ debug(5, "IMuseDigital::setFade(%d) - setting", soundId);
track->volFadeDelay = delay60HzTicks;
track->volFadeDest = destVolume * 1000;
track->volFadeStep = (track->volFadeDest - track->vol) * 60 * (1000 / _callbackFps) / (1000 * delay60HzTicks);
@@ -301,40 +273,92 @@
}
}
+void IMuseDigital::fadeOutMusicAndStartNew(int fadeDelay, const char *filename, int soundId) {
+ Common::StackLock lock(_mutex, "IMuseDigital::fadeOutMusicAndStartNew()");
+ debug(5, "IMuseDigital::fadeOutMusicAndStartNew(fade:%d, file:%s, sound:%d)", fadeDelay, filename, soundId);
+
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ Track *track = _track[l];
+ if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+ debug(5, "IMuseDigital::fadeOutMusicAndStartNew(sound:%d) - starting", soundId);
+ startMusicWithOtherPos(filename, soundId, 0, 127, track);
+ cloneToFadeOutTrack(track, fadeDelay);
+ flushTrack(track);
+ break;
+ }
+ }
+}
+
void IMuseDigital::fadeOutMusic(int fadeDelay) {
Common::StackLock lock(_mutex, "IMuseDigital::fadeOutMusic()");
- debug(5, "IMuseDigital::fadeOutMusic");
+ debug(5, "IMuseDigital::fadeOutMusic(fade:%d)", fadeDelay);
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+ debug(5, "IMuseDigital::fadeOutMusic(fade:%d, soound:%d)", fadeDelay, track->soundId);
cloneToFadeOutTrack(track, fadeDelay);
- track->toBeRemoved = true;
+ flushTrack(track);
+ break;
}
}
}
-IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(Track *track, int fadeDelay) {
+void IMuseDigital::setHookIdForMusic(int hookId) {
+ Common::StackLock lock(_mutex, "IMuseDigital::setHookIdForMusic()");
+ debug(5, "IMuseDigital::setHookIdForMusic(hookId:%d)", hookId);
+
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ Track *track = _track[l];
+ if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
+ debug(5, "IMuseDigital::setHookIdForMusic - setting for sound:%d", track->soundId);
+ track->curHookId = hookId;
+ break;
+ }
+ }
+}
+
+void IMuseDigital::setTrigger(TriggerParams *trigger) {
+ Common::StackLock lock(_mutex, "IMuseDigital::setTrigger()");
+ debug(5, "IMuseDigital::setTrigger(%s)", trigger->filename);
+
+ memcpy(&_triggerParams, trigger, sizeof(TriggerParams));
+ _triggerUsed = true;
+}
+
+Track *IMuseDigital::cloneToFadeOutTrack(Track *track, int fadeDelay) {
assert(track);
- Track *fadeTrack = 0;
+ Track *fadeTrack;
- debug(0, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", track->trackId, fadeDelay);
+ debug(5, "cloneToFadeOutTrack(soundId:%d, fade:%d) - begin of func", track->trackId, fadeDelay);
- if (_track[track->trackId + MAX_DIGITAL_TRACKS]->used) {
- warning("IMuseDigital::cloneToFadeOutTrack: Not free fade track");
+ if (track->toBeRemoved) {
+ error("cloneToFadeOutTrack: Tried to clone a track to be removed, please bug report");
return NULL;
}
+ assert(track->trackId < MAX_DIGITAL_TRACKS);
fadeTrack = _track[track->trackId + MAX_DIGITAL_TRACKS];
+ if (fadeTrack->used) {
+ debug(5, "cloneToFadeOutTrack: No free fade track, force flush fade soundId:%d", fadeTrack->soundId);
+ flushTrack(fadeTrack);
+ _mixer->stopHandle(fadeTrack->mixChanHandle);
+ }
+
// Clone the settings of the given track
memcpy(fadeTrack, track, sizeof(Track));
+ fadeTrack->trackId = track->trackId + MAX_DIGITAL_TRACKS;
- // Clone the sound. We use the original sound in the fadeTrack,
- // and the cloned sound in the original track. This fixes bug #1635361.
- assert(fadeTrack->soundDesc);
- track->soundDesc = _sound->cloneSound(fadeTrack->soundDesc);
- assert(track->soundDesc);
+ // Clone the sound.
+ // leaving bug number for now #1635361
+ ImuseDigiSndMgr::SoundDesc *soundDesc = _sound->cloneSound(track->soundDesc);
+ if (!soundDesc) {
+ // it fail load open old song after switch to diffrent CDs
+ // so gave up
+ error("Game not supported while playing on 2 diffrent CDs");
+ }
+ track->soundDesc = soundDesc;
// Set the volume fading parameters to indicate a fade out
fadeTrack->volFadeDelay = fadeDelay;
@@ -343,27 +367,12 @@
fadeTrack->volFadeUsed = true;
// Create an appendable output buffer
- Audio::Mixer::SoundType type;
- switch (fadeTrack->volGroupId) {
- case 1:
- type = Audio::Mixer::kSpeechSoundType;
- break;
- case 2:
- type = Audio::Mixer::kSFXSoundType;
- break;
- case 3:
- type = Audio::Mixer::kMusicSoundType;
- break;
- default:
- type = Audio::Mixer::kPlainSoundType;
- break;
- }
fadeTrack->stream = Audio::makeAppendableAudioStream(_sound->getFreq(fadeTrack->soundDesc), makeMixerFlags(fadeTrack->mixerFlags));
- _mixer->playInputStream(type, &fadeTrack->mixChanHandle, fadeTrack->stream, -1, fadeTrack->vol / 1000, fadeTrack->pan, false);
-
- fadeTrack->mixerStreamRunning = true;
+ _mixer->playInputStream(track->getType(), &fadeTrack->mixChanHandle, fadeTrack->stream, -1, fadeTrack->getVol(), fadeTrack->getPan());
fadeTrack->used = true;
+ debug(5, "cloneToFadeOutTrack() - end of func, soundId %d, fade soundId %d", track->soundId, fadeTrack->soundId);
+
return fadeTrack;
}
Copied: scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.h (from rev 30627, scummvm/trunk/engines/scumm/imuse_digi/dimuse_track.h)
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.h (rev 0)
+++ scummvm/branches/branch-0-11-0/engines/scumm/imuse_digi/dimuse_track.h 2008-01-23 23:43:06 UTC (rev 30628)
@@ -0,0 +1,101 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#if !defined(SCUMM_IMUSE_DIGI_TRACK_H) && !defined(DISABLE_SCUMM_7_8)
+#define SCUMM_IMUSE_DIGI_TRACK_H
+
+#include "common/scummsys.h"
+
+namespace Scumm {
+
+
+// These flag bits correspond exactly to the sound mixer flags of March 2007.
+// We don't want to use the mixer flags directly, because then our saved games
+// will break in interesting ways if the mixer flags are ever assigned new
+// values. Now they should keep working, as long as these flags don't change.
+
+enum {
+ kFlagUnsigned = 1 << 0,
+ kFlag16Bits = 1 << 1,
+ kFlagLittleEndian = 1 << 2,
+ kFlagStereo = 1 << 3,
+ kFlagReverseStereo = 1 << 4
+
+ // Not used by Digital iMUSE
+ // kFlagAutoFree = 1 << 5,
+ // kFlagLoop = 1 << 6
+};
+
+struct Track {
+ int trackId; // used to identify track by value (0-15)
+
+ int8 pan; // panning value of sound
+ int32 vol; // volume level (values 0-127 * 1000)
+ int32 volFadeDest; // volume level which fading target (values 0-127 * 1000)
+ int32 volFadeStep; // delta of step while changing volume at each imuse callback
+ int32 volFadeDelay; // time in ms how long fading volume must be
+ bool volFadeUsed; // flag if fading is in progress
+
+ int32 soundId; // sound id used by scumm script
+ char soundName[15]; // sound name but also filename of sound in bundle data
+ bool used; // flag mean that track is used
+ bool toBeRemoved; // flag mean that track need to be free
+ bool mixerStreamRunning; // flag mean sound mixer's stream is running OBSOLETE
+ bool souStreamUsed; // flag mean that track use stream from sou file
+ bool sndDataExtComp;// flag mean that sound data is compressed by scummvm tools
+ int32 soundPriority;// priority level of played sound (0-127)
+ int32 regionOffset; // offset to sound data relative to begining of current region
+ int32 dataOffset; // offset to sound data relative to begining of 'DATA' chunk
+ int32 curRegion; // id of current used region
+ int32 curHookId; // id of current used hook id
+ int32 volGroupId; // id of volume group (IMUSE_VOLGRP_VOICE, IMUSE_VOLGRP_SFX, IMUSE_VOLGRP_MUSIC)
+ int32 soundType; // type of sound data (kSpeechSoundType, kSFXSoundType, kMusicSoundType)
+ int32 feedSize; // size of sound data needed to be filled at each callback iteration
+ int32 dataMod12Bit; // value used between all callback to align 12 bit source of data
+ int32 mixerFlags; // flags for sound mixer's channel (kFlagStereo, kFlag16Bits, kFlagReverseStereo, kFlagUnsigned, kFlagLittleEndian)
+
+ ImuseDigiSndMgr::SoundDesc *soundDesc; // sound handle used by iMuse sound manager
+ Audio::SoundHandle mixChanHandle; // sound mixer's channel handle
+ Audio::AppendableAudioStream *stream; // sound mixer's audio stream handle for *.la1 and *.bun
+
+ Track() : soundId(-1), used(false), stream(NULL) {
+ }
+
+ int getPan() const { return (pan != 64) ? 2 * pan - 127 : 0; }
+ int getVol() const { return vol / 1000; }
+ Audio::Mixer::SoundType getType() const {
+ Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
+ if (volGroupId == 1)
+ type = Audio::Mixer::kSpeechSoundType;
+ else if (volGroupId == 2)
+ type = Audio::Mixer::kSFXSoundType;
+ else if (volGroupId == 3)
+ type = Audio::Mixer::kMusicSoundType;
+ return type;
+ }
+};
+
+} // End of namespace Scumm
+
+#endif
Modified: scummvm/branches/branch-0-11-0/engines/scumm/scumm.cpp
===================================================================
--- scummvm/branches/branch-0-11-0/engines/scumm/scumm.cpp 2008-01-23 23:12:56 UTC (rev 30627)
+++ scummvm/branches/branch-0-11-0/engines/scumm/scumm.cpp 2008-01-23 23:43:06 UTC (rev 30628)
@@ -2116,8 +2116,8 @@
ScummEngine_v6::scummLoop_handleSound();
if (_imuseDigital) {
_imuseDigital->flushTracks();
- // In CoMI and the full (non-demo) version of The Dig, also invoke IMuseDigital::refreshScripts
- if ( ((_game.id == GID_DIG) && (!(_game.features & GF_DEMO))) || (_game.id == GID_CMI) )
+ // In CoMI and the Dig the full (non-demo) version invoke IMuseDigital::refreshScripts
+ if ((_game.id == GID_DIG || _game.id == GID_CMI) && !(_game.features & GF_DEMO))
_imuseDigital->refreshScripts();
}
if (_smixer) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list