diff options
author | Travis Howell | 2009-01-09 05:14:56 +0000 |
---|---|---|
committer | Travis Howell | 2009-01-09 05:14:56 +0000 |
commit | 1e29a3c7d8acfa4dcede922225bfda7e67a53eab (patch) | |
tree | b38900405b34831f022c17b84ba0ebf92b7f57cc /engines | |
parent | 02f4098a1ac86d830777d91c4961f22c072392e4 (diff) | |
download | scummvm-rg350-1e29a3c7d8acfa4dcede922225bfda7e67a53eab.tar.gz scummvm-rg350-1e29a3c7d8acfa4dcede922225bfda7e67a53eab.tar.bz2 scummvm-rg350-1e29a3c7d8acfa4dcede922225bfda7e67a53eab.zip |
Correct sound priority and SBNG offsets, in later HE games.
svn-id: r35795
Diffstat (limited to 'engines')
-rw-r--r-- | engines/scumm/he/resource_he.cpp | 161 | ||||
-rw-r--r-- | engines/scumm/he/sound_he.cpp | 188 |
2 files changed, 176 insertions, 173 deletions
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp index 1c288d4e14..ebe13f29a4 100644 --- a/engines/scumm/he/resource_he.cpp +++ b/engines/scumm/he/resource_he.cpp @@ -1665,167 +1665,6 @@ int ScummEngine_v72he::getSoundResourceSize(int id) { return size; } -byte *getSoundOffset(byte *ptr) { - byte *endPtr; - uint32 offset, size; - - if (READ_BE_UINT32(ptr) != MKID_BE('RIFF')) - return NULL; - - endPtr = (ptr + 12); - size = READ_LE_UINT32(ptr + 4) - 4; - - while (size > 0) { - offset = READ_LE_UINT32(endPtr + 4); - - if (offset <= 0) - error("Illegal chunk length - %d bytes.", offset); - - if (offset > size) - error("Chunk extends beyond file end - %d versus %d.", offset, size); - - if (READ_BE_UINT32(endPtr) == MKID_BE('data')) - return endPtr; - - endPtr = endPtr + offset + 8; - } - - return NULL; -} - -void ScummEngine_v80he::createSound(int snd1id, int snd2id) { - byte *snd1Ptr, *snd2Ptr; - byte *sbng1Ptr, *sbng2Ptr; - byte *sdat1Ptr, *sdat2Ptr; - byte *src, *dst, *tmp; - int len, offs, size; - int sdat1size, sdat2size; - - sbng1Ptr = NULL; - sbng2Ptr = NULL; - - if (snd2id == -1) { - _sndPtrOffs = 0; - _sndTmrOffs = 0; - _sndDataSize = 0; - return; - } - - if (snd1id != _curSndId) { - _curSndId = snd1id; - _sndPtrOffs = 0; - _sndTmrOffs = 0; - _sndDataSize = 0; - } - - snd1Ptr = getResourceAddress(rtSound, snd1id); - assert(snd1Ptr); - snd2Ptr = getResourceAddress(rtSound, snd2id); - assert(snd2Ptr); - - int i; - int chan = -1; - for (i = 0; i < ARRAYSIZE(((SoundHE *)_sound)->_heChannel); i++) { - if (((SoundHE *)_sound)->_heChannel[i].sound == snd1id) - chan = i; - } - - if (!getSoundOffset(snd1Ptr)) { - sbng1Ptr = heFindResource(MKID_BE('SBNG'), snd1Ptr); - sbng2Ptr = heFindResource(MKID_BE('SBNG'), snd2Ptr); - } - - if (sbng1Ptr != NULL && sbng2Ptr != NULL) { - if (chan != -1 && ((SoundHE *)_sound)->_heChannel[chan].codeOffs > 0) { - int curOffs = ((SoundHE *)_sound)->_heChannel[chan].codeOffs; - - src = snd1Ptr + curOffs; - dst = sbng1Ptr + 8; - size = READ_BE_UINT32(sbng1Ptr + 4); - len = sbng1Ptr - snd1Ptr + size - curOffs; - - byte *data = (byte *)malloc(len); - memcpy(data, src, len); - memcpy(dst, data, len); - free(data); - - dst = sbng1Ptr + 8; - while ((size = READ_LE_UINT16(dst)) != 0) - dst += size; - } else { - dst = sbng1Ptr + 8; - } - - ((SoundHE *)_sound)->_heChannel[chan].codeOffs = sbng1Ptr - snd1Ptr + 8; - - tmp = sbng2Ptr + 8; - while ((offs = READ_LE_UINT16(tmp)) != 0) { - tmp += offs; - } - - src = sbng2Ptr + 8; - len = tmp - sbng2Ptr - 6; - memcpy(dst, src, len); - - int32 time; - while ((size = READ_LE_UINT16(dst)) != 0) { - time = READ_LE_UINT32(dst + 2); - time += _sndTmrOffs; - WRITE_LE_UINT32(dst + 2, time); - dst += size; - } - } - - if (getSoundOffset(snd1Ptr)) { - sdat1Ptr = getSoundOffset(snd1Ptr); - assert(sdat1Ptr); - sdat2Ptr = getSoundOffset(snd2Ptr); - assert(sdat2Ptr); - - if (!_sndDataSize) - _sndDataSize = READ_LE_UINT32(sdat1Ptr + 4) - 8; - - sdat2size = READ_LE_UINT32(sdat2Ptr + 4) - 8; - } else { - sdat1Ptr = heFindResource(MKID_BE('SDAT'), snd1Ptr); - assert(sdat1Ptr); - sdat2Ptr = heFindResource(MKID_BE('SDAT'), snd2Ptr); - assert(sdat2Ptr); - - _sndDataSize = READ_BE_UINT32(sdat1Ptr + 4) - 8; - - sdat2size = READ_BE_UINT32(sdat2Ptr + 4) - 8; - } - - sdat1size = _sndDataSize - _sndPtrOffs; - if (sdat2size < sdat1size) { - src = sdat2Ptr + 8; - dst = sdat1Ptr + 8 + _sndPtrOffs; - len = sdat2size; - - memcpy(dst, src, len); - - _sndPtrOffs += sdat2size; - _sndTmrOffs += sdat2size; - } else { - src = sdat2Ptr + 8; - dst = sdat1Ptr + 8 + _sndPtrOffs; - len = sdat1size; - - memcpy(dst, src, len); - - if (sdat2size != sdat1size) { - src = sdat2Ptr + 8 + sdat1size; - dst = sdat1Ptr + 8; - len = sdat2size - sdat1size; - - memcpy(dst, src, len); - } - - _sndPtrOffs = sdat2size - sdat1size; - _sndTmrOffs += sdat2size; - } -} #endif } // End of namespace Scumm diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index e03a6366a4..56b2326be8 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -491,6 +491,38 @@ void SoundHE::processSoundOpcodes(int sound, byte *codePtr, int *soundVars) { } } +byte *findSoundTag(uint32 tag, byte *ptr) { + byte *endPtr; + uint32 offset, size; + + if (READ_BE_UINT32(ptr) == MKID_BE('WSOU')) { + ptr += 8; + } + + if (READ_BE_UINT32(ptr) != MKID_BE('RIFF')) + return NULL; + + endPtr = (ptr + 12); + size = READ_LE_UINT32(ptr + 4); + + while (endPtr < ptr + size) { + offset = READ_LE_UINT32(endPtr + 4); + + if (offset <= 0) + error("Illegal chunk length - %d bytes.", offset); + + if (offset > size) + error("Chunk extends beyond file end - %d versus %d.", offset, size); + + if (READ_BE_UINT32(endPtr) == tag) + return endPtr; + + endPtr = endPtr + offset + 8; + } + + return NULL; +} + void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) { byte *ptr, *spoolPtr; int size = -1; @@ -552,16 +584,17 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) return; } - // Support for sound in later Backyard sports games + // Support for sound in later HE games if (READ_BE_UINT32(ptr) == MKID_BE('RIFF') || READ_BE_UINT32(ptr) == MKID_BE('WSOU')) { uint16 compType; int blockAlign; char *sound; + int codeOffs = -1; - priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18); - - if (READ_BE_UINT32(ptr) == MKID_BE('WSOU')) - ptr += 8; + byte *sbngPtr = findSoundTag(MKID_BE('SBNG'), ptr); + if (sbngPtr != NULL) { + codeOffs = sbngPtr - ptr + 8; + } if (_mixer->isSoundHandleActive(_heSoundChannels[heChannel])) { int curSnd = _heChannel[heChannel].sound; @@ -571,10 +604,8 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) return; } - int codeOffs = -1; - if (READ_BE_UINT32(ptr + 36) == MKID_BE('SBNG')) { - codeOffs = 36; - } + if (READ_BE_UINT32(ptr) == MKID_BE('WSOU')) + ptr += 8; size = READ_LE_UINT32(ptr + 4); Common::MemoryReadStream stream(ptr, size); @@ -587,7 +618,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) _vm->setHETimer(heChannel + 4); _heChannel[heChannel].sound = soundID; - _heChannel[heChannel].priority = priority; + _heChannel[heChannel].priority = (soundID > _vm->_numSounds) ? 255 : 128; _heChannel[heChannel].sbngBlock = (codeOffs != -1) ? 1 : 0; _heChannel[heChannel].codeOffs = codeOffs; memset(_heChannel[heChannel].soundVars, 0, sizeof(_heChannel[heChannel].soundVars)); @@ -618,6 +649,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) // Support for sound in Humongous Entertainment games else if (READ_BE_UINT32(ptr) == MKID_BE('DIGI') || READ_BE_UINT32(ptr) == MKID_BE('TALK')) { byte *sndPtr = ptr; + int codeOffs = -1; priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18); rate = READ_LE_UINT16(ptr + 22); @@ -633,7 +665,6 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) return; } - int codeOffs = -1; if (READ_BE_UINT32(ptr) == MKID_BE('SBNG')) { codeOffs = ptr - sndPtr + 8; ptr += READ_BE_UINT32(ptr + 4); @@ -670,7 +701,6 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) _mixer->stopHandle(_heSoundChannels[heChannel]); _mixer->playRaw(type, &_heSoundChannels[heChannel], ptr + heOffset + 8, size, rate, flags, soundID); - } // Support for PCM music in 3DO versions of Humongous Entertainment games else if (READ_BE_UINT32(ptr) == MKID_BE('MRAW')) { @@ -730,4 +760,138 @@ void SoundHE::startHETalkSound(uint32 offset) { addSoundToQueue2(1, 0, channel, 0); } +void ScummEngine_v80he::createSound(int snd1id, int snd2id) { + byte *snd1Ptr, *snd2Ptr; + byte *sbng1Ptr, *sbng2Ptr; + byte *sdat1Ptr, *sdat2Ptr; + byte *src, *dst, *tmp; + int len, offs, size; + int sdat1size, sdat2size; + + sbng1Ptr = NULL; + sbng2Ptr = NULL; + + if (snd2id == -1) { + _sndPtrOffs = 0; + _sndTmrOffs = 0; + _sndDataSize = 0; + return; + } + + if (snd1id != _curSndId) { + _curSndId = snd1id; + _sndPtrOffs = 0; + _sndTmrOffs = 0; + _sndDataSize = 0; + } + + snd1Ptr = getResourceAddress(rtSound, snd1id); + assert(snd1Ptr); + snd2Ptr = getResourceAddress(rtSound, snd2id); + assert(snd2Ptr); + + int i; + int chan = -1; + for (i = 0; i < ARRAYSIZE(((SoundHE *)_sound)->_heChannel); i++) { + if (((SoundHE *)_sound)->_heChannel[i].sound == snd1id) + chan = i; + } + + if (!findSoundTag(MKID_BE('data'), snd1Ptr)) { + sbng1Ptr = heFindResource(MKID_BE('SBNG'), snd1Ptr); + sbng2Ptr = heFindResource(MKID_BE('SBNG'), snd2Ptr); + } + + if (sbng1Ptr != NULL && sbng2Ptr != NULL) { + if (chan != -1 && ((SoundHE *)_sound)->_heChannel[chan].codeOffs > 0) { + int curOffs = ((SoundHE *)_sound)->_heChannel[chan].codeOffs; + + src = snd1Ptr + curOffs; + dst = sbng1Ptr + 8; + size = READ_BE_UINT32(sbng1Ptr + 4); + len = sbng1Ptr - snd1Ptr + size - curOffs; + + byte *data = (byte *)malloc(len); + memcpy(data, src, len); + memcpy(dst, data, len); + free(data); + + dst = sbng1Ptr + 8; + while ((size = READ_LE_UINT16(dst)) != 0) + dst += size; + } else { + dst = sbng1Ptr + 8; + } + + ((SoundHE *)_sound)->_heChannel[chan].codeOffs = sbng1Ptr - snd1Ptr + 8; + + tmp = sbng2Ptr + 8; + while ((offs = READ_LE_UINT16(tmp)) != 0) { + tmp += offs; + } + + src = sbng2Ptr + 8; + len = tmp - sbng2Ptr - 6; + memcpy(dst, src, len); + + int32 time; + while ((size = READ_LE_UINT16(dst)) != 0) { + time = READ_LE_UINT32(dst + 2); + time += _sndTmrOffs; + WRITE_LE_UINT32(dst + 2, time); + dst += size; + } + } + + if (findSoundTag(MKID_BE('data'), snd1Ptr)) { + sdat1Ptr = findSoundTag(MKID_BE('data'), snd1Ptr); + assert(sdat1Ptr); + sdat2Ptr = findSoundTag(MKID_BE('data'), snd2Ptr); + assert(sdat2Ptr); + + if (!_sndDataSize) + _sndDataSize = READ_LE_UINT32(sdat1Ptr + 4) - 8; + + sdat2size = READ_LE_UINT32(sdat2Ptr + 4) - 8; + } else { + sdat1Ptr = heFindResource(MKID_BE('SDAT'), snd1Ptr); + assert(sdat1Ptr); + sdat2Ptr = heFindResource(MKID_BE('SDAT'), snd2Ptr); + assert(sdat2Ptr); + + _sndDataSize = READ_BE_UINT32(sdat1Ptr + 4) - 8; + + sdat2size = READ_BE_UINT32(sdat2Ptr + 4) - 8; + } + + sdat1size = _sndDataSize - _sndPtrOffs; + if (sdat2size < sdat1size) { + src = sdat2Ptr + 8; + dst = sdat1Ptr + 8 + _sndPtrOffs; + len = sdat2size; + + memcpy(dst, src, len); + + _sndPtrOffs += sdat2size; + _sndTmrOffs += sdat2size; + } else { + src = sdat2Ptr + 8; + dst = sdat1Ptr + 8 + _sndPtrOffs; + len = sdat1size; + + memcpy(dst, src, len); + + if (sdat2size != sdat1size) { + src = sdat2Ptr + 8 + sdat1size; + dst = sdat1Ptr + 8; + len = sdat2size - sdat1size; + + memcpy(dst, src, len); + } + + _sndPtrOffs = sdat2size - sdat1size; + _sndTmrOffs += sdat2size; + } +} + } // End of namespace Scumm |