scummvm/engines/kyra/sound/sound_adlib.cpp
athrxx e28f6e1ead KYRA: - fix some license headers
Remove LGPL license part from files that shouldn't have them. I missed that when I rearranged that code a couple of weeks ago.
2019-04-30 01:12:25 +02:00

258 lines
6.3 KiB
C++

/* 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.
*
*/
#include "kyra/sound/sound_intern.h"
#include "kyra/sound/drivers/adlib.h"
#include "common/system.h"
#include "common/config-manager.h"
namespace Kyra {
// Kyra 1 sound triggers. Most noticeably, these are used towards the end of
// the game, in the castle, to cycle between different songs. The same music is
// used in other places throughout the game, but the player is less likely to
// spend enough time there to notice.
const int SoundAdLibPC::_kyra1SoundTriggers[] = {
0, 4, 5, 3
};
const int SoundAdLibPC::_kyra1NumSoundTriggers = ARRAYSIZE(SoundAdLibPC::_kyra1SoundTriggers);
SoundAdLibPC::SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer)
: Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) {
memset(_trackEntries, 0, sizeof(_trackEntries));
_soundTriggers = 0;
_numSoundTriggers = 0;
_sfxPlayingSound = -1;
_soundFileLoaded.clear();
_currentResourceSet = 0;
memset(&_resInfo, 0, sizeof(_resInfo));
switch (vm->game()) {
case GI_LOL:
_version = _vm->gameFlags().isDemo ? 3 : 4;
break;
case GI_KYRA2:
_version = 4;
break;
case GI_KYRA1:
_version = 3;
_soundTriggers = _kyra1SoundTriggers;
_numSoundTriggers = _kyra1NumSoundTriggers;
break;
case GI_EOB2:
_version = 2;
break;
case GI_EOB1:
_version = 1;
break;
default:
break;
}
_driver = new AdLibDriver(mixer, _version);
assert(_driver);
}
SoundAdLibPC::~SoundAdLibPC() {
delete _driver;
delete[] _soundDataPtr;
for (int i = 0; i < 3; i++)
initAudioResourceInfo(i, 0);
}
bool SoundAdLibPC::init() {
_driver->initDriver();
return true;
}
void SoundAdLibPC::process() {
int trigger = _driver->getSoundTrigger();
if (trigger < _numSoundTriggers) {
int soundId = _soundTriggers[trigger];
if (soundId)
playTrack(soundId);
} else {
warning("Unknown sound trigger %d", trigger);
// TODO: At this point, we really want to clear the trigger...
}
}
void SoundAdLibPC::updateVolumeSettings() {
bool mute = false;
if (ConfMan.hasKey("mute"))
mute = ConfMan.getBool("mute");
int newMusicVolume = mute ? 0 : ConfMan.getInt("music_volume");
//newMusicVolume = (newMusicVolume * 145) / Audio::Mixer::kMaxMixerVolume + 110;
newMusicVolume = CLIP(newMusicVolume, 0, 255);
int newSfxVolume = mute ? 0 : ConfMan.getInt("sfx_volume");
//newSfxVolume = (newSfxVolume * 200) / Audio::Mixer::kMaxMixerVolume + 55;
newSfxVolume = CLIP(newSfxVolume, 0, 255);
_driver->setMusicVolume(newMusicVolume);
_driver->setSfxVolume(newSfxVolume);
}
void SoundAdLibPC::playTrack(uint8 track) {
if (_musicEnabled) {
// WORKAROUND: There is a bug in the Kyra 1 "Pool of Sorrow"
// music which causes the channels to get progressively out of
// sync for each loop. To avoid that, we declare that all four
// of the song channels have to jump "in sync".
if (track == 4 && _soundFileLoaded.equalsIgnoreCase("KYRA1B.ADL"))
_driver->setSyncJumpMask(0x000F);
else
_driver->setSyncJumpMask(0);
play(track, 0xFF);
}
}
void SoundAdLibPC::haltTrack() {
play(0, 0);
play(0, 0);
//_vm->_system->delayMillis(3 * 60);
}
bool SoundAdLibPC::isPlaying() const {
return _driver->isChannelPlaying(0);
}
void SoundAdLibPC::playSoundEffect(uint8 track, uint8 volume) {
if (_sfxEnabled)
play(track, volume);
}
void SoundAdLibPC::play(uint8 track, uint8 volume) {
uint16 soundId = 0;
if (_version == 4)
soundId = READ_LE_UINT16(&_trackEntries[track<<1]);
else
soundId = _trackEntries[track];
if ((soundId == 0xFFFF && _version == 4) || (soundId == 0xFF && _version < 4) || !_soundDataPtr)
return;
_driver->queueTrack(soundId, volume);
}
void SoundAdLibPC::beginFadeOut() {
play(_version > 2 ? 1 : 15, 0xFF);
}
int SoundAdLibPC::checkTrigger() {
return _driver->getSoundTrigger();
}
void SoundAdLibPC::resetTrigger() {
_driver->resetSoundTrigger();
}
void SoundAdLibPC::initAudioResourceInfo(int set, void *info) {
if (set >= kMusicIntro && set <= kMusicFinale) {
delete _resInfo[set];
_resInfo[set] = info ? new SoundResourceInfo_PC(*(SoundResourceInfo_PC*)info) : 0;
}
}
void SoundAdLibPC::selectAudioResourceSet(int set) {
if (set >= kMusicIntro && set <= kMusicFinale) {
if (_resInfo[set])
_currentResourceSet = set;
}
}
bool SoundAdLibPC::hasSoundFile(uint file) const {
if (file < res()->fileListSize)
return (res()->fileList[file] != 0);
return false;
}
void SoundAdLibPC::loadSoundFile(uint file) {
if (file < res()->fileListSize)
internalLoadFile(res()->fileList[file]);
}
void SoundAdLibPC::loadSoundFile(Common::String file) {
internalLoadFile(file);
}
void SoundAdLibPC::internalLoadFile(Common::String file) {
file += ((_version == 1) ? ".DAT" : ".ADL");
if (_soundFileLoaded == file)
return;
if (_soundDataPtr)
haltTrack();
uint8 *fileData = 0; uint32 fileSize = 0;
fileData = _vm->resource()->fileData(file.c_str(), &fileSize);
if (!fileData) {
warning("Couldn't find music file: '%s'", file.c_str());
return;
}
playSoundEffect(0);
playSoundEffect(0);
_driver->stopAllChannels();
_soundDataPtr = 0;
int soundDataSize = fileSize;
uint8 *p = fileData;
if (_version == 4) {
memcpy(_trackEntries, p, 500);
p += 500;
soundDataSize -= 500;
} else {
memcpy(_trackEntries, p, 120);
p += 120;
soundDataSize -= 120;
}
_soundDataPtr = new uint8[soundDataSize];
assert(_soundDataPtr);
memcpy(_soundDataPtr, p, soundDataSize);
delete[] fileData;
fileData = p = 0;
fileSize = 0;
_driver->setSoundData(_soundDataPtr, soundDataSize);
_soundFileLoaded = file;
}
} // End of namespace Kyra