diff options
author | athrxx | 2011-11-06 00:46:58 +0100 |
---|---|---|
committer | Johannes Schickel | 2011-12-26 16:18:09 +0100 |
commit | 77a81a80b4157acd7e8e580c2648ec3b3ef6bc64 (patch) | |
tree | dc6a21036c29a0817d0a59116066b3287e09f955 /engines/kyra | |
parent | 8c3488a973fb93895d542c0b55548bb96101b187 (diff) | |
download | scummvm-rg350-77a81a80b4157acd7e8e580c2648ec3b3ef6bc64.tar.gz scummvm-rg350-77a81a80b4157acd7e8e580c2648ec3b3ef6bc64.tar.bz2 scummvm-rg350-77a81a80b4157acd7e8e580c2648ec3b3ef6bc64.zip |
KYRA: (AdLib Driver) - implement sound effects volume
(also make internal driver version more flexible)
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/sound.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/sound.h | 4 | ||||
-rw-r--r-- | engines/kyra/sound_adlib.cpp | 101 | ||||
-rw-r--r-- | engines/kyra/sound_adlib.h | 6 | ||||
-rw-r--r-- | engines/kyra/sound_amiga.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/sound_intern.h | 10 | ||||
-rw-r--r-- | engines/kyra/sound_midi.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/sound_towns.cpp | 6 |
8 files changed, 68 insertions, 67 deletions
diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index a1af1ad6f8..9325513066 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -229,8 +229,8 @@ bool MixedSoundDriver::isPlaying() const { return _music->isPlaying() | _sfx->isPlaying(); } -void MixedSoundDriver::playSoundEffect(uint8 track) { - _sfx->playSoundEffect(track); +void MixedSoundDriver::playSoundEffect(uint8 track, uint8 volume) { + _sfx->playSoundEffect(track, volume); } void MixedSoundDriver::stopAllSoundEffects() { diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index f3de56520e..88454e4878 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -128,7 +128,7 @@ public: * * @param track sound effect id */ - virtual void playSoundEffect(uint8 track) = 0; + virtual void playSoundEffect(uint8 track, uint8 volume = 0xff) = 0; /** * Stop playback of all sfx tracks. @@ -273,7 +273,7 @@ public: virtual void haltTrack(); virtual bool isPlaying() const; - virtual void playSoundEffect(uint8 track); + virtual void playSoundEffect(uint8 track, uint8 volume = 0xff); virtual void stopAllSoundEffects(); diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index b04abea080..c31cf809ee 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -57,12 +57,12 @@ namespace Kyra { class AdLibDriver : public Audio::AudioStream { public: - AdLibDriver(Audio::Mixer *mixer, bool v2); + AdLibDriver(Audio::Mixer *mixer, int version); ~AdLibDriver(); void initDriver(); void setSoundData(uint8 *data); - void queueTrack(int track); + void queueTrack(int track, int volume); bool isChannelPlaying(int channel) const; void stopAllChannels(); int getSoundTrigger() const { return _soundTrigger; } @@ -223,7 +223,7 @@ private: } uint8 *getInstrument(int instrumentId) { - return _soundData + READ_LE_UINT16(_soundData + (_v2 ? 1000 : 500) + 2 * instrumentId); + return _soundData + READ_LE_UINT16(_soundData + ((_version == 2) ? 1000 : 500) + 2 * instrumentId); } void setupPrograms(); @@ -358,11 +358,16 @@ private: uint8 *_soundData; + struct QueueEntry { + uint8 *data; + uint8 volume; + }; + + QueueEntry _programQueue[16]; int _programStartTimeout; - uint8 *_programQueue[16]; int _programQueueStart, _programQueueEnd; - void adjustSfxData(uint8 *data); + void adjustSfxData(uint8 *data, int volume); uint8 *_sfxPointer; int _sfxPriority; int _sfxVelocity; @@ -394,13 +399,13 @@ private: uint8 _musicVolume, _sfxVolume; - bool _v2; + int _version; }; -AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { +AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) { setupParserOpcodeTable(); - _v2 = v2; + _version = version; _mixer = mixer; @@ -467,7 +472,7 @@ void AdLibDriver::setMusicVolume(uint8 volume) { } // For now we use the music volume for both sfx and music in Kyra1. - if (!_v2) { + if (_version < 2) { _sfxVolume = volume; for (uint i = 6; i < 9; ++i) { @@ -484,8 +489,8 @@ void AdLibDriver::setMusicVolume(uint8 volume) { } void AdLibDriver::setSfxVolume(uint8 volume) { - // We only support sfx volume in v2 games. - if (!_v2) + // We only support sfx volume in version 2 games. + if (_version < 2) return; Common::StackLock lock(_mutex); @@ -525,20 +530,21 @@ void AdLibDriver::setSoundData(uint8 *data) { _soundData = data; } -void AdLibDriver::queueTrack(int track) { +void AdLibDriver::queueTrack(int track, int volume) { Common::StackLock lock(_mutex); uint8 *trackData = getProgram(track); if (!trackData) return; - if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd] != 0) { + if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd].data != 0) { warning("AdLibDriver: Program queue full, dropping track %d", track); return; } - _programQueue[_programQueueEnd++] = trackData; - _programQueueEnd &= 15; + _programQueue[_programQueueEnd].data = trackData; + _programQueue[_programQueueEnd].volume = volume; + _programQueueEnd = (_programQueueEnd + 1) & 15; } bool AdLibDriver::isChannelPlaying(int channel) const { @@ -588,13 +594,13 @@ void AdLibDriver::setupPrograms() { if (_programQueueStart == _programQueueEnd) return; - uint8 *ptr = _programQueue[_programQueueStart]; + uint8 *ptr = _programQueue[_programQueueStart].data; // Clear the queue entry - _programQueue[_programQueueStart] = 0; + _programQueue[_programQueueStart].data = 0; _programQueueStart = (_programQueueStart + 1) & 15; // Adjust data in case we hit a sound effect. - adjustSfxData(ptr); + adjustSfxData(ptr, _programQueue[_programQueueStart].volume); const int chan = *ptr++; const int priority = *ptr++; @@ -626,7 +632,7 @@ void AdLibDriver::setupPrograms() { } } -void AdLibDriver::adjustSfxData(uint8 *ptr) { +void AdLibDriver::adjustSfxData(uint8 *ptr, int volume) { // Check whether we need to reset the data of an old sfx which has been // started. if (_sfxPointer) { @@ -647,21 +653,16 @@ void AdLibDriver::adjustSfxData(uint8 *ptr) { _sfxPriority = ptr[1]; _sfxVelocity = ptr[3]; - // In the cases I've seen, the mysterious fourth byte has been - // the parameter for the update_setExtraLevel3() callback. - // - // The extra level is part of the channels "total level", which - // is a six-bit value where larger values means softer volume. - // - // So what seems to be happening here is that sounds which are - // started by this function are given a slightly lower priority - // and a slightly higher (i.e. softer) extra level 3 than they - // would have if they were started from anywhere else. Strange. - // Adjust the values. - int newVal = ((((ptr[3]) + 63) * 0xFF) >> 8) & 0xFF; - ptr[3] = -newVal + 63; - ptr[1] = ((ptr[1] * 0xFF) >> 8) & 0xFF; + if (_version >= 1) { + int newVal = ((((ptr[3]) + 63) * volume) >> 8) & 0xFF; + ptr[3] = -newVal + 63; + ptr[1] = ((ptr[1] * volume) >> 8) & 0xFF; + } else { + int newVal = ((_sfxVelocity << 2) ^ 0xff) * volume; + ptr[3] = (newVal >> 10) ^ 0x3f; + ptr[1] = newVal >> 11; + } } // A few words on opcode parsing and timing: @@ -2238,20 +2239,20 @@ const int SoundAdLibPC::_kyra1NumSoundTriggers = ARRAYSIZE(SoundAdLibPC::_kyra1S SoundAdLibPC::SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) { memset(_trackEntries, 0, sizeof(_trackEntries)); - _v2 = (_vm->game() == GI_KYRA2) || (_vm->game() == GI_LOL && !_vm->gameFlags().isDemo); - _driver = new AdLibDriver(mixer, _v2); + _version = ((_vm->game() == GI_KYRA2) || (_vm->game() == GI_LOL && !_vm->gameFlags().isDemo)) ? 2 : 1; + _driver = new AdLibDriver(mixer, _version); assert(_driver); _sfxPlayingSound = -1; _soundFileLoaded.clear(); - if (_v2) { + if (_version == 1) { + _soundTriggers = _kyra1SoundTriggers; + _numSoundTriggers = _kyra1NumSoundTriggers; + } else { // TODO: Figure out if Kyra 2 uses sound triggers at all. _soundTriggers = 0; _numSoundTriggers = 0; - } else { - _soundTriggers = _kyra1SoundTriggers; - _numSoundTriggers = _kyra1NumSoundTriggers; } } @@ -2307,13 +2308,13 @@ void SoundAdLibPC::playTrack(uint8 track) { _driver->setSyncJumpMask(0x000F); else _driver->setSyncJumpMask(0); - play(track); + play(track, 0xff); } } void SoundAdLibPC::haltTrack() { - play(0); - play(0); + play(0, 0); + play(0, 0); //_vm->_system->delayMillis(3 * 60); } @@ -2321,27 +2322,27 @@ bool SoundAdLibPC::isPlaying() const { return _driver->isChannelPlaying(0); } -void SoundAdLibPC::playSoundEffect(uint8 track) { +void SoundAdLibPC::playSoundEffect(uint8 track, uint8 volume) { if (_sfxEnabled) - play(track); + play(track, volume); } -void SoundAdLibPC::play(uint8 track) { +void SoundAdLibPC::play(uint8 track, uint8 volume) { uint16 soundId = 0; - if (_v2) + if (_version == 2) soundId = READ_LE_UINT16(&_trackEntries[track<<1]); else soundId = _trackEntries[track]; - if ((soundId == 0xFFFF && _v2) || (soundId == 0xFF && !_v2) || !_soundDataPtr) + if ((soundId == 0xFFFF && _version == 2) || (soundId == 0xFF && _version < 2) || !_soundDataPtr) return; - _driver->queueTrack(soundId); + _driver->queueTrack(soundId, volume); } void SoundAdLibPC::beginFadeOut() { - play(1); + play(1, 0xff); } void SoundAdLibPC::loadSoundFile(uint file) { @@ -2377,7 +2378,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) { int soundDataSize = fileSize; uint8 *p = fileData; - if (_v2) { + if (_version == 2) { memcpy(_trackEntries, p, 500); p += 500; soundDataSize -= 500; diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h index 923a4cb75f..06ec9515ff 100644 --- a/engines/kyra/sound_adlib.h +++ b/engines/kyra/sound_adlib.h @@ -76,17 +76,17 @@ public: virtual void haltTrack(); virtual bool isPlaying() const; - virtual void playSoundEffect(uint8 track); + virtual void playSoundEffect(uint8 track, uint8 volume = 0xff); virtual void beginFadeOut(); private: void internalLoadFile(Common::String file); - void play(uint8 track); + void play(uint8 track, uint8 volume); AdLibDriver *_driver; - bool _v2; + int _version; uint8 _trackEntries[500]; uint8 *_soundDataPtr; int _sfxPlayingSound; diff --git a/engines/kyra/sound_amiga.cpp b/engines/kyra/sound_amiga.cpp index dfb0aa8bf3..ec2748dd38 100644 --- a/engines/kyra/sound_amiga.cpp +++ b/engines/kyra/sound_amiga.cpp @@ -173,7 +173,7 @@ void SoundAmiga::beginFadeOut() { _driver->setVolume(0x40); } -void SoundAmiga::playSoundEffect(uint8 track) { +void SoundAmiga::playSoundEffect(uint8 track, uint8) { debugC(5, kDebugLevelSound, "SoundAmiga::playSoundEffect(%d)", track); const AmigaSfxTable *sfx = 0; bool pan = false; diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h index be3c09de96..427bef66e2 100644 --- a/engines/kyra/sound_intern.h +++ b/engines/kyra/sound_intern.h @@ -67,7 +67,7 @@ public: void haltTrack(); bool isPlaying() const; - void playSoundEffect(uint8 track); + void playSoundEffect(uint8 track, uint8 volume = 0xff); void stopAllSoundEffects(); void beginFadeOut(); @@ -116,7 +116,7 @@ public: void playTrack(uint8 track); void haltTrack(); - void playSoundEffect(uint8); + void playSoundEffect(uint8 track, uint8 volume = 0xff); void stopAllSoundEffects(); void beginFadeOut(); @@ -166,7 +166,7 @@ public: void beginFadeOut(); int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; } - void playSoundEffect(uint8); + void playSoundEffect(uint8 track, uint8 volume = 0xff); void updateVolumeSettings(); @@ -195,7 +195,7 @@ public: void beginFadeOut(); int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx); - void playSoundEffect(uint8 track); + void playSoundEffect(uint8 track, uint8 volume = 0xff); void updateVolumeSettings(); @@ -304,7 +304,7 @@ public: void beginFadeOut(); int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; } - void playSoundEffect(uint8); + void playSoundEffect(uint8 track, uint8 volume = 0xff); protected: Audio::MaxTrax *_driver; diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp index 1a5c2f94ac..0004395f6f 100644 --- a/engines/kyra/sound_midi.cpp +++ b/engines/kyra/sound_midi.cpp @@ -684,7 +684,7 @@ bool SoundMidiPC::isPlaying() const { return _music->isPlaying(); } -void SoundMidiPC::playSoundEffect(uint8 track) { +void SoundMidiPC::playSoundEffect(uint8 track, uint8) { if (!_sfxEnabled) return; diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index c851842f22..b77c307872 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -125,7 +125,7 @@ void SoundTowns::loadSoundFile(uint file) { _sfxFileData = _vm->resource()->fileData(fileListEntry(file), 0); } -void SoundTowns::playSoundEffect(uint8 track) { +void SoundTowns::playSoundEffect(uint8 track, uint8) { if (!_sfxEnabled || !_sfxFileData) return; @@ -446,7 +446,7 @@ void SoundPC98::beginFadeOut() { haltTrack(); } -void SoundPC98::playSoundEffect(uint8 track) { +void SoundPC98::playSoundEffect(uint8 track, uint8) { if (!_sfxTrackData) return; @@ -650,7 +650,7 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, return 1; } -void SoundTownsPC98_v2::playSoundEffect(uint8 track) { +void SoundTownsPC98_v2::playSoundEffect(uint8 track, uint8) { if (!_useFmSfx || !_sfxTrackData) return; |