diff options
Diffstat (limited to 'engines/sky')
-rw-r--r-- | engines/sky/music/adlibchannel.cpp | 12 | ||||
-rw-r--r-- | engines/sky/music/adlibchannel.h | 5 | ||||
-rw-r--r-- | engines/sky/music/adlibmusic.cpp | 56 | ||||
-rw-r--r-- | engines/sky/music/adlibmusic.h | 18 |
4 files changed, 32 insertions, 59 deletions
diff --git a/engines/sky/music/adlibchannel.cpp b/engines/sky/music/adlibchannel.cpp index 8400fef6eb..c7acb9b6c1 100644 --- a/engines/sky/music/adlibchannel.cpp +++ b/engines/sky/music/adlibchannel.cpp @@ -29,7 +29,7 @@ namespace Sky { -AdLibChannel::AdLibChannel(FM_OPL *opl, uint8 *pMusicData, uint16 startOfData) { +AdLibChannel::AdLibChannel(OPL::OPL *opl, uint8 *pMusicData, uint16 startOfData) { _opl = opl; _musicData = pMusicData; _channelData.loopPoint = startOfData; @@ -45,6 +45,8 @@ AdLibChannel::AdLibChannel(FM_OPL *opl, uint8 *pMusicData, uint16 startOfData) { _channelData.frequency = 0; _channelData.instrumentData = NULL; + _musicVolume = 128; + uint16 instrumentDataLoc; if (SkyEngine::_systemVars.gameVersion == 109) { @@ -86,7 +88,7 @@ bool AdLibChannel::isActive() { } void AdLibChannel::updateVolume(uint16 pVolume) { - // Do nothing. The mixer handles the music volume for us. + _musicVolume = pVolume; } /* This class uses the same area for the register mirror as the original @@ -95,7 +97,7 @@ void AdLibChannel::updateVolume(uint16 pVolume) { */ void AdLibChannel::setRegister(uint8 regNum, uint8 value) { if (_adlibRegMirror[regNum] != value) { - OPLWriteReg (_opl, regNum, value); + _opl->writeReg(regNum, value); _adlibRegMirror[regNum] = value; } } @@ -208,6 +210,8 @@ void AdLibChannel::setupChannelVolume(uint8 volume) { uint32 resVol = ((volume + 1) * (_channelData.instrumentData->totOutLev_Op2 + 1)) << 1; resVol &= 0xFFFF; resVol *= (_channelData.channelVolume + 1) << 1; + resVol >>= 8; + resVol *= _musicVolume << 1; resVol >>= 16; assert(resVol < 0x81); resultOp = ((_channelData.instrumentData->scalingLevel << 6) & 0xC0) | _opOutputTable[resVol]; @@ -216,6 +220,8 @@ void AdLibChannel::setupChannelVolume(uint8 volume) { resVol = ((volume + 1) * (_channelData.instrumentData->totOutLev_Op1 + 1)) << 1; resVol &= 0xFFFF; resVol *= (_channelData.channelVolume + 1) << 1; + resVol >>= 8; + resVol *= _musicVolume << 1; resVol >>= 16; } else resVol = _channelData.instrumentData->totOutLev_Op1; diff --git a/engines/sky/music/adlibchannel.h b/engines/sky/music/adlibchannel.h index 80dae93b2c..4504e3b570 100644 --- a/engines/sky/music/adlibchannel.h +++ b/engines/sky/music/adlibchannel.h @@ -60,14 +60,15 @@ typedef struct { class AdLibChannel : public ChannelBase { public: - AdLibChannel (FM_OPL *opl, uint8 *pMusicData, uint16 startOfData); + AdLibChannel (OPL::OPL *opl, uint8 *pMusicData, uint16 startOfData); virtual ~AdLibChannel(); virtual uint8 process(uint16 aktTime); virtual void updateVolume(uint16 pVolume); virtual bool isActive(); private: - FM_OPL *_opl; + OPL::OPL *_opl; uint8 *_musicData; + uint16 _musicVolume; AdLibChannelType _channelData; InstrumentStruct *_instruments; diff --git a/engines/sky/music/adlibmusic.cpp b/engines/sky/music/adlibmusic.cpp index dd64c5bc81..be5e7b2353 100644 --- a/engines/sky/music/adlibmusic.cpp +++ b/engines/sky/music/adlibmusic.cpp @@ -22,6 +22,7 @@ #include "common/endian.h" +#include "common/textconsole.h" #include "sky/music/adlibmusic.h" #include "sky/music/adlibchannel.h" @@ -32,44 +33,21 @@ namespace Sky { AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) { _driverFileBase = 60202; - _sampleRate = pMixer->getOutputRate(); - _opl = makeAdLibOPL(_sampleRate); + _opl = OPL::Config::create(); + if (!_opl || !_opl->init()) + error("Failed to create OPL"); - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + _opl->start(new Common::Functor0Mem<void, AdLibMusic>(this, &AdLibMusic::onTimer), 50); } AdLibMusic::~AdLibMusic() { - OPLDestroy(_opl); - _mixer->stopHandle(_soundHandle); + delete _opl; } -int AdLibMusic::readBuffer(int16 *data, const int numSamples) { - if (_musicData == NULL) { - // no music loaded - memset(data, 0, numSamples * sizeof(int16)); - } else if ((_currentMusic == 0) || (_numberOfChannels == 0)) { - // music loaded but not played as of yet - memset(data, 0, numSamples * sizeof(int16)); - // poll anyways as pollMusic() can activate the music +void AdLibMusic::onTimer() { + if (_musicData != NULL) pollMusic(); - _nextMusicPoll = _sampleRate / 50; - } else { - uint32 render; - uint remaining = numSamples; - while (remaining) { - render = (remaining > _nextMusicPoll) ? _nextMusicPoll : remaining; - remaining -= render; - _nextMusicPoll -= render; - YM3812UpdateOne(_opl, data, render); - data += render; - if (_nextMusicPoll == 0) { - pollMusic(); - _nextMusicPoll = _sampleRate / 50; - } - } - } - return numSamples; } void AdLibMusic::setupPointers() { @@ -87,7 +65,6 @@ void AdLibMusic::setupPointers() { _musicDataLoc = READ_LE_UINT16(_musicData + 0x1201); _initSequence = _musicData + 0xE91; } - _nextMusicPoll = 0; } void AdLibMusic::setupChannels(uint8 *channelData) { @@ -102,26 +79,15 @@ void AdLibMusic::setupChannels(uint8 *channelData) { void AdLibMusic::startDriver() { uint16 cnt = 0; while (_initSequence[cnt] || _initSequence[cnt + 1]) { - OPLWriteReg (_opl, _initSequence[cnt], _initSequence[cnt + 1]); + _opl->writeReg(_initSequence[cnt], _initSequence[cnt + 1]); cnt += 2; } } void AdLibMusic::setVolume(uint16 param) { _musicVolume = param; - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, 2 * param); -} - -bool AdLibMusic::isStereo() const { - return false; -} - -bool AdLibMusic::endOfData() const { - return false; -} - -int AdLibMusic::getRate() const { - return _sampleRate; + for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++) + _channels[cnt]->updateVolume(_musicVolume); } } // End of namespace Sky diff --git a/engines/sky/music/adlibmusic.h b/engines/sky/music/adlibmusic.h index 886eef026e..7b51f2d3a0 100644 --- a/engines/sky/music/adlibmusic.h +++ b/engines/sky/music/adlibmusic.h @@ -25,32 +25,32 @@ #include "sky/music/musicbase.h" #include "audio/audiostream.h" -#include "audio/fmopl.h" + +namespace OPL { +class OPL; +} namespace Sky { -class AdLibMusic : public Audio::AudioStream, public MusicBase { +class AdLibMusic : public MusicBase { public: AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk); ~AdLibMusic(); // AudioStream API - int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const; - bool endOfData() const; - int getRate() const; virtual void setVolume(uint16 param); private: - FM_OPL *_opl; - Audio::SoundHandle _soundHandle; + OPL::OPL *_opl; uint8 *_initSequence; - uint32 _sampleRate, _nextMusicPoll; + uint32 _sampleRate; virtual void setupPointers(); virtual void setupChannels(uint8 *channelData); virtual void startDriver(); void premixerCall(int16 *buf, uint len); + + void onTimer(); }; } // End of namespace Sky |