mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-09 03:10:22 +00:00
e28f6e1ead
Remove LGPL license part from files that shouldn't have them. I missed that when I rearranged that code a couple of weeks ago.
258 lines
6.3 KiB
C++
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
|