Fix sound channel selection in HE95+ games.

svn-id: r20040
This commit is contained in:
Travis Howell 2006-01-15 08:37:01 +00:00
parent 0e88d466ec
commit 5db5e59701
7 changed files with 55 additions and 32 deletions

View File

@ -1702,7 +1702,7 @@ void ScummEngine_v100he::o100_startSound() {
_heSndSoundId = pop();
_heSndOffset = 0;
_heSndSoundFreq = 11025;
_heSndChannel = VAR(VAR_MUSIC_CHANNEL);
_heSndChannel = VAR(VAR_SOUND_CHANNEL);
_heSndFlags = 0;
break;
case 133:

View File

@ -463,7 +463,7 @@ void ScummEngine_v70he::o70_startSound() {
_heSndSoundId = pop();
_heSndOffset = 0;
_heSndSoundFreq = 11025;
_heSndChannel = VAR(VAR_MUSIC_CHANNEL);
_heSndChannel = VAR(VAR_SOUND_CHANNEL);
break;
case 245:
_heSndFlags |= 1;

View File

@ -1357,10 +1357,10 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
VAR_REDRAW_ALL_ACTORS = 0xFF;
VAR_SKIP_RESET_TALK_ACTOR = 0xFF;
VAR_MUSIC_CHANNEL = 0xFF;
VAR_SOUND_CHANNEL = 0xFF;
VAR_TALK_CHANNEL = 0xFF;
VAR_SOUNDCODE_TMR = 0xFF;
VAR_DEFAULT_SOUND_CHANNEL = 0xFF;
VAR_RESERVED_SOUND_CHANNELS = 0xFF;
VAR_MAIN_SCRIPT = 0xFF;

View File

@ -1332,10 +1332,10 @@ public:
byte VAR_REDRAW_ALL_ACTORS;
byte VAR_SKIP_RESET_TALK_ACTOR;
byte VAR_MUSIC_CHANNEL;
byte VAR_SOUND_CHANNEL;
byte VAR_TALK_CHANNEL;
byte VAR_SOUNDCODE_TMR;
byte VAR_DEFAULT_SOUND_CHANNEL;
byte VAR_RESERVED_SOUND_CHANNELS;
byte VAR_MAIN_SCRIPT;

View File

@ -102,7 +102,7 @@ public: // Used by createSound()
int priority;
int sbngBlock;
int soundVars[27];
} _heChannel[9];
} _heChannel[8];
public:
Audio::SoundHandle _talkChannelHandle; // Handle of mixer channel actor is talking on
@ -143,6 +143,7 @@ public:
// HE specific
bool getHEMusicDetails(int id, int &musicOffs, int &musicSize);
int findFreeSoundChannel();
int isSoundCodeUsed(int sound);
int getSoundPos(int sound);
int getSoundVar(int sound, int var);

View File

@ -43,6 +43,27 @@
namespace Scumm {
int Sound::findFreeSoundChannel() {
int chan, min;
min = _vm->VAR(_vm->VAR_RESERVED_SOUND_CHANNELS);
if (min == 0) {
_vm->VAR(_vm->VAR_RESERVED_SOUND_CHANNELS) = 8;
return 1;
}
if (min < 8) {
for (chan = min; min < ARRAYSIZE(_heChannel); chan++) {
if (_vm->_mixer->isSoundHandleActive(_heSoundChannels[chan]) == 0)
return chan;
}
} else {
return 1;
}
return min;
}
int Sound::isSoundCodeUsed(int sound) {
int chan = -1;
for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
@ -290,20 +311,16 @@ void Sound::processSoundOpcodes(int sound, byte *codePtr, int *soundVars) {
}
void Sound::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
debug(0,"playHESound: soundID %d heOffset %d heChannel %d heFlags %d", soundID, heOffset, heChannel, heFlags);
byte *ptr, *spoolPtr;
char *sound;
int size = -1;
int priority, rate;
byte flags = Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE;
if (heChannel == -1) {
if (_vm->_heversion >= 95 && _vm->VAR(_vm->VAR_DEFAULT_SOUND_CHANNEL) != 0) {
heChannel = _vm->VAR(_vm->VAR_DEFAULT_SOUND_CHANNEL);
} else {
heChannel = 1;
}
}
if (heChannel == -1)
heChannel = (_vm->VAR_RESERVED_SOUND_CHANNELS != 0xFF) ? findFreeSoundChannel() : 1;
debug(0,"playHESound: soundID %d heOffset %d heChannel %d heFlags %d", soundID, heOffset, heChannel, heFlags);
if (soundID > _vm->_numSounds) {
if (soundID >= 10000) {
@ -360,10 +377,19 @@ void Sound::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
return;
}
// TODO: Extra sound flags
if (heFlags & 1) {
//flags |= Audio::Mixer::FLAG_LOOP;
}
// Support for sound in later Backyard sports games
if (READ_UINT32(ptr) == MKID('RIFF')) {
if (READ_UINT32(ptr) == MKID('RIFF') || READ_UINT32(ptr) == MKID('WSOU')) {
uint16 type;
int blockAlign;
if (READ_UINT32(ptr) == MKID('WSOU'))
ptr += 8;
size = READ_LE_UINT32(ptr + 4);
Common::MemoryReadStream stream(ptr, size);
@ -382,6 +408,7 @@ void Sound::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
sound = (char *)malloc(size);
memcpy(sound, ptr + stream.pos(), size);
}
_vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
_vm->_mixer->playRaw(&_heSoundChannels[heChannel], sound, size, rate, flags, soundID);
}
// Support for sound in Humongous Entertainment games
@ -392,12 +419,11 @@ void Sound::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
rate = READ_LE_UINT16(ptr + 22);
ptr += 8 + READ_BE_UINT32(ptr + 12);
// TODO
/* if (_vm->_mixer->isSoundHandleActive(_heSoundChannels[heChannel])) {
if (_vm->_mixer->isSoundHandleActive(_heSoundChannels[heChannel])) {
int curSnd = _heChannel[heChannel].sound;
if (curSnd != 0 && curSnd != 1 && soundID != 1 && _heChannel[heChannel].priority > priority)
return;
} */
}
int codeOffs = -1;
if (READ_UINT32(ptr) == MKID('SBNG')) {
@ -420,14 +446,10 @@ void Sound::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
_overrideFreq = 0;
}
// TODO
if (heFlags & 1) {
//flags |= Audio::Mixer::FLAG_LOOP;
}
// Allocate a sound buffer, copy the data into it, and play
sound = (char *)malloc(size);
memcpy(sound, ptr + heOffset + 8, size);
_vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
_vm->_mixer->playRaw(&_heSoundChannels[heChannel], sound, size, rate, flags, soundID);
_vm->setHETimer(heChannel + 4);
@ -485,7 +507,7 @@ void Sound::startHETalkSound(uint32 offset) {
ptr = _vm->getResourceAddress(rtSound, 1);
_sfxFile->read(ptr, size);
int channel = (_vm->VAR_SOUND_CHANNEL != 0xFF) ? _vm->VAR(_vm->VAR_SOUND_CHANNEL) : 0;
int channel = (_vm->VAR_TALK_CHANNEL != 0xFF) ? _vm->VAR(_vm->VAR_TALK_CHANNEL) : 0;
addSoundToQueue2(1, 0, channel, 0);
}

View File

@ -214,8 +214,8 @@ void ScummEngine_v70he::setupScummVars() {
VAR_MUSIC_TIMER = 0xFF;
VAR_NUM_SOUND_CHANNELS = 9;
VAR_SOUND_CHANNEL = 10;
VAR_MUSIC_CHANNEL = 14;
VAR_TALK_CHANNEL = 10;
VAR_SOUND_CHANNEL = 14;
}
void ScummEngine_v72he::setupScummVars() {
@ -266,8 +266,8 @@ void ScummEngine_v72he::setupScummVars() {
VAR_CHARINC = 48;
VAR_TALK_ACTOR = 49;
VAR_LAST_SOUND = 50;
VAR_SOUND_CHANNEL = 51;
VAR_MUSIC_CHANNEL = 52;
VAR_TALK_CHANNEL = 51;
VAR_SOUND_CHANNEL = 52;
VAR_MEMORY_PERFORMANCE = 57;
VAR_VIDEO_PERFORMANCE = 58;
@ -312,7 +312,7 @@ void ScummEngine_v72he::setupScummVars() {
VAR_U32_VERSION = 107;
VAR_U32_ARRAY_UNK = 116;
VAR_WIZ_TCOLOR = 117;
VAR_DEFAULT_SOUND_CHANNEL = 120;
VAR_RESERVED_SOUND_CHANNELS = 120;
}
if (_heversion >= 98) {
VAR_SKIP_RESET_TALK_ACTOR = 125;
@ -581,8 +581,8 @@ void ScummEngine_v70he::initScummVars() {
VAR(VAR_MACHINE_SPEED) = 13;
VAR(VAR_NUM_SOUND_CHANNELS) = 8;
VAR(VAR_MUSIC_CHANNEL) = 1;
VAR(VAR_SOUND_CHANNEL) = 2;
VAR(VAR_SOUND_CHANNEL) = 1;
VAR(VAR_TALK_CHANNEL) = 2;
}
void ScummEngine_v72he::initScummVars() {