diff options
author | Paul Gilbert | 2011-06-05 08:42:26 +1000 |
---|---|---|
committer | Paul Gilbert | 2011-06-05 08:42:26 +1000 |
commit | b855a87d708b292df2813c0f676fd411a1021d81 (patch) | |
tree | 12103cabb614b2a3ec3b59e322939c0b3ef18963 | |
parent | 12464b101fc92f0f148f59e906829c568280a455 (diff) | |
download | scummvm-rg350-b855a87d708b292df2813c0f676fd411a1021d81.tar.gz scummvm-rg350-b855a87d708b292df2813c0f676fd411a1021d81.tar.bz2 scummvm-rg350-b855a87d708b292df2813c0f676fd411a1021d81.zip |
TSAGE: Removed CRUISE sound code that didn't work
-rw-r--r-- | engines/tsage/sound.cpp | 612 | ||||
-rw-r--r-- | engines/tsage/sound.h | 170 |
2 files changed, 1 insertions, 781 deletions
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index ac77edd7d9..e3d746ecd6 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -586,40 +586,6 @@ void SoundManager::_sfRethinkVoiceTypes() { ++sfManager()._suspendCtr; _sfDereferenceAll(); - // Check for any active sound currently playing - for (Common::List<Sound *>::iterator playIterator = sfManager()._playList.begin(); - playIterator != sfManager()._playList.end(); ++playIterator) { - Sound *sound = *playIterator; - if (sound->getCueValue() >= 0) { - // Currently playing sound - // TODO: Figure out how to determine when raw playback has ended - return; - } - } - - // No currently playing sound, so look for any queued sounds to play - for (Common::List<Sound *>::iterator playIterator = sfManager()._playList.begin(); - playIterator != sfManager()._playList.end(); ++playIterator) { - Sound *sound = *playIterator; - if (sound->getCueValue() == -1) { - // Found a sound to start playing - - // Get the first sound driver - assert(sfManager()._installedDrivers.size() > 0); - SoundDriver *driver = *sfManager()._installedDrivers.begin(); - - // Start each channel of the sound - for (int channelNum = 0; channelNum < sound->_trackInfo._count; ++channelNum) { - const byte *data = sound->_trackInfo._channelData[channelNum]; - int dataSize = _vm->_memoryManager.getSize(data); - - driver->play(data, dataSize, channelNum, sfManager()._volume); - } - - sound->_cueValue = 0; - return; - } - } } @@ -1155,582 +1121,6 @@ SoundDriver::SoundDriver() { /*--------------------------------------------------------------------------*/ -const int PCSoundDriver::_noteTable[] = { - 0xEEE, 0xE17, 0xD4D, 0xC8C, 0xBD9, 0xB2F, 0xA8E, 0x9F7, - 0x967, 0x8E0, 0x861, 0x7E8, 0x777, 0x70B, 0x6A6, 0x647, - 0x5EC, 0x597, 0x547, 0x4FB, 0x4B3, 0x470, 0x430, 0x3F4, - 0x3BB, 0x385, 0x353, 0x323, 0x2F6, 0x2CB, 0x2A3, 0x27D, - 0x259, 0x238, 0x218, 0x1FA, 0x1DD, 0x1C2, 0x1A9, 0x191, - 0x17B, 0x165, 0x151, 0x13E, 0x12C, 0x11C, 0x10C, 0x0FD, - 0x0EE, 0x0E1, 0x0D4, 0x0C8, 0x0BD, 0x0B2, 0x0A8, 0x09F, - 0x096, 0x08E, 0x086, 0x07E, 0x077, 0x070, 0x06A, 0x064, - 0x05E, 0x059, 0x054, 0x04F, 0x04B, 0x047, 0x043, 0x03F, - 0x03B, 0x038, 0x035, 0x032, 0x02F, 0x02C, 0x02A, 0x027, - 0x025, 0x023, 0x021, 0x01F, 0x01D, 0x01C, 0x01A, 0x019, - 0x017, 0x016, 0x015, 0x013, 0x012, 0x011, 0x010, 0x00F -}; - -const int PCSoundDriver::_noteTableCount = ARRAYSIZE(_noteTable); - -void PCSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) { - _upCb = upCb; - _upRef = ref; -} - -void PCSoundDriver::findNote(int freq, int *note, int *oct) const { - *note = _noteTableCount - 1; - for (int i = 0; i < _noteTableCount; ++i) { - if (_noteTable[i] <= freq) { - *note = i; - break; - } - } - - *oct = *note / 12; - *note %= 12; -} - -void PCSoundDriver::resetChannel(int channel) { - stopChannel(channel); - stopAll(); -} - -void PCSoundDriver::syncSounds() { - bool mute = false; - if (ConfMan.hasKey("mute")) - mute = ConfMan.getBool("mute"); - - bool music_mute = mute; - bool sfx_mute = mute; - - if (!mute) { - music_mute = ConfMan.getBool("music_mute"); - sfx_mute = ConfMan.getBool("sfx_mute"); - } - - // Get the new music and sfx volumes - _musicVolume = music_mute ? 0 : MIN(255, ConfMan.getInt("music_volume")); - _sfxVolume = sfx_mute ? 0 : MIN(255, ConfMan.getInt("sfx_volume")); -} - -/*--------------------------------------------------------------------------*/ - -const int AdlibDriverBase::_freqTable[] = { - 0x157, 0x16C, 0x181, 0x198, 0x1B1, 0x1CB, - 0x1E6, 0x203, 0x222, 0x243, 0x266, 0x28A -}; - -const int AdlibDriverBase::_freqTableCount = ARRAYSIZE(_freqTable); - -const int AdlibDriverBase::_operatorsTable[] = { - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 -}; - -const int AdlibDriverBase::_operatorsTableCount = ARRAYSIZE(_operatorsTable); - -const int AdlibDriverBase::_voiceOperatorsTable[] = { - 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 16, 16, 14, 14, 17, 17, 13, 13 -}; - -const int AdlibDriverBase::_voiceOperatorsTableCount = ARRAYSIZE(_voiceOperatorsTable); - - -AdlibDriverBase::AdlibDriverBase(Audio::Mixer *mixer) - : _mixer(mixer) { - _sampleRate = _mixer->getOutputRate(); - _opl = makeAdLibOPL(_sampleRate); - - for (int i = 0; i < 5; ++i) { - _channelsVolumeTable[i].original = 0; - _channelsVolumeTable[i].adjusted = 0; - } - memset(_instrumentsTable, 0, sizeof(_instrumentsTable)); - initCard(); - _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); - - _musicVolume = ConfMan.getBool("music_mute") ? 0 : MIN(255, ConfMan.getInt("music_volume")); - _sfxVolume = ConfMan.getBool("sfx_mute") ? 0 : MIN(255, ConfMan.getInt("sfx_volume")); -} - -AdlibDriverBase::~AdlibDriverBase() { - _mixer->stopHandle(_soundHandle); - OPLDestroy(_opl); -} - -void AdlibDriverBase::syncSounds() { - PCSoundDriver::syncSounds(); - - // Force all instruments to reload on the next playing point - for (int i = 0; i < 5; ++i) { - adjustVolume(i, _channelsVolumeTable[i].original); - AdLibSoundInstrument *ins = &_instrumentsTable[i]; - setupInstrument(ins, i); - } -} - -void AdlibDriverBase::adjustVolume(int channel, int volume) { - _channelsVolumeTable[channel].original = volume; - - if (volume > 80) { - volume = 80; - } else if (volume < 0) { - volume = 0; - } - volume += volume / 4; - if (volume > 127) { - volume = 127; - } - - int volAdjust = (channel == 4) ? _sfxVolume : _musicVolume; - volume = (volume * volAdjust) / 128; - - if (volume > 127) - volume = 127; - - _channelsVolumeTable[channel].adjusted = volume; -} - -void AdlibDriverBase::setupChannel(int channel, const byte *data, int instrument, int volume) { - assert(channel < 5); - if (data) { - adjustVolume(channel, volume); - setupInstrument(data, channel); - } -} - -void AdlibDriverBase::stopChannel(int channel) { - assert(channel < 5); - AdLibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins->mode != 0 && ins->channel == 6) { - channel = 6; - } - if (ins->mode == 0 || channel == 6) { - OPLWriteReg(_opl, 0xB0 | channel, 0); - } - if (ins->mode != 0) { - _vibrato &= ~(1 << (10 - ins->channel)); - OPLWriteReg(_opl, 0xBD, _vibrato); - } -} - -void AdlibDriverBase::stopAll() { - int i; - for (i = 0; i < 18; ++i) { - OPLWriteReg(_opl, 0x40 | _operatorsTable[i], 63); - } - for (i = 0; i < 9; ++i) { - OPLWriteReg(_opl, 0xB0 | i, 0); - } - OPLWriteReg(_opl, 0xBD, 0); -} - -int AdlibDriverBase::readBuffer(int16 *buffer, const int numSamples) { - update(buffer, numSamples); - return numSamples; -} - -void AdlibDriverBase::initCard() { - _vibrato = 0x20; - OPLWriteReg(_opl, 0xBD, _vibrato); - OPLWriteReg(_opl, 0x08, 0x40); - - static const int oplRegs[] = { 0x40, 0x60, 0x80, 0x20, 0xE0 }; - - for (int i = 0; i < 9; ++i) { - OPLWriteReg(_opl, 0xB0 | i, 0); - } - for (int i = 0; i < 9; ++i) { - OPLWriteReg(_opl, 0xC0 | i, 0); - } - - for (int j = 0; j < 5; j++) { - for (int i = 0; i < 18; ++i) { - OPLWriteReg(_opl, oplRegs[j] | _operatorsTable[i], 0); - } - } - - OPLWriteReg(_opl, 1, 0x20); - OPLWriteReg(_opl, 1, 0); -} - -void AdlibDriverBase::update(int16 *buf, int len) { - static int samplesLeft = 0; - while (len != 0) { - int count = samplesLeft; - if (count > len) { - count = len; - } - samplesLeft -= count; - len -= count; - YM3812UpdateOne(_opl, buf, count); - if (samplesLeft == 0) { - if (_upCb) { - (*_upCb)(_upRef); - } - samplesLeft = _sampleRate / 50; - } - buf += count; - } -} - -void AdlibDriverBase::setupInstrument(const byte *data, int channel) { - AdLibSoundInstrument *ins = &_instrumentsTable[channel]; - loadInstrument(data, ins); - - setupInstrument(ins, channel); -} - -void AdlibDriverBase::setupInstrument(const AdLibSoundInstrument *ins, int channel) { - int mod, car, tmp; - const AdLibRegisterSoundInstrument *reg; - - if (ins->mode != 0) { - mod = _operatorsTable[_voiceOperatorsTable[2 * ins->channel + 0]]; - car = _operatorsTable[_voiceOperatorsTable[2 * ins->channel + 1]]; - } else { - mod = _operatorsTable[_voiceOperatorsTable[2 * channel + 0]]; - car = _operatorsTable[_voiceOperatorsTable[2 * channel + 1]]; - } - - if (ins->mode == 0 || ins->channel == 6) { - reg = &ins->regMod; - OPLWriteReg(_opl, 0x20 | mod, reg->vibrato); - if (reg->freqMod) { - tmp = reg->outputLevel & 0x3F; - } else { - tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel].adjusted; - tmp = 63 - (2 * tmp + 127) / (2 * 127); - } - OPLWriteReg(_opl, 0x40 | mod, tmp | (reg->keyScaling << 6)); - OPLWriteReg(_opl, 0x60 | mod, reg->attackDecay); - OPLWriteReg(_opl, 0x80 | mod, reg->sustainRelease); - if (ins->mode != 0) { - OPLWriteReg(_opl, 0xC0 | ins->channel, reg->feedbackStrength); - } else { - OPLWriteReg(_opl, 0xC0 | channel, reg->feedbackStrength); - } - OPLWriteReg(_opl, 0xE0 | mod, ins->waveSelectMod); - } - - reg = &ins->regCar; - OPLWriteReg(_opl, 0x20 | car, reg->vibrato); - tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel].adjusted; - tmp = 63 - (2 * tmp + 127) / (2 * 127); - OPLWriteReg(_opl, 0x40 | car, tmp | (reg->keyScaling << 6)); - OPLWriteReg(_opl, 0x60 | car, reg->attackDecay); - OPLWriteReg(_opl, 0x80 | car, reg->sustainRelease); - OPLWriteReg(_opl, 0xE0 | car, ins->waveSelectCar); -} - -void AdlibDriverBase::loadRegisterInstrument(const byte *data, AdLibRegisterSoundInstrument *reg) { - reg->vibrato = 0; - if (READ_LE_UINT16(data + 18)) { // amplitude vibrato - reg->vibrato |= 0x80; - } - if (READ_LE_UINT16(data + 20)) { // frequency vibrato - reg->vibrato |= 0x40; - } - if (READ_LE_UINT16(data + 10)) { // sustaining sound - reg->vibrato |= 0x20; - } - if (READ_LE_UINT16(data + 22)) { // envelope scaling - reg->vibrato |= 0x10; - } - reg->vibrato |= READ_LE_UINT16(data + 2) & 0xF; // frequency multiplier - - reg->attackDecay = READ_LE_UINT16(data + 6) << 4; // attack rate - reg->attackDecay |= READ_LE_UINT16(data + 12) & 0xF; // decay rate - - reg->sustainRelease = READ_LE_UINT16(data + 8) << 4; // sustain level - reg->sustainRelease |= READ_LE_UINT16(data + 14) & 0xF; // release rate - - reg->feedbackStrength = READ_LE_UINT16(data + 4) << 1; // feedback - if (READ_LE_UINT16(data + 24) == 0) { // frequency modulation - reg->feedbackStrength |= 1; - } - - reg->keyScaling = READ_LE_UINT16(data); - reg->outputLevel = READ_LE_UINT16(data + 16); - reg->freqMod = READ_LE_UINT16(data + 24); -} - -/*--------------------------------------------------------------------------*/ - -void AdlibSoundDriverADL::loadInstrument(const byte *data, AdLibSoundInstrument *asi) { - asi->mode = *data++; - asi->channel = *data++; - asi->waveSelectMod = *data++ & 3; - asi->waveSelectCar = *data++ & 3; - asi->amDepth = *data++; - ++data; - loadRegisterInstrument(data, &asi->regMod); data += 26; - loadRegisterInstrument(data, &asi->regCar); data += 26; -} - -void AdlibSoundDriverADL::setChannelFrequency(int channel, int frequency) { - assert(channel < 5); - AdLibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins->mode != 0) { - channel = ins->channel; - if (channel == 9) { - channel = 8; - } else if (channel == 10) { - channel = 7; - } - } - int freq, note, oct; - findNote(frequency, ¬e, &oct); - - note += oct * 12; - if (ins->amDepth) { - note = ins->amDepth; - } - if (note < 0) { - note = 0; - } - - freq = _freqTable[note % 12]; - OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); - if (ins->mode == 0) { - freq |= 0x20; - } - OPLWriteReg(_opl, 0xB0 | channel, freq); - if (ins->mode != 0) { - _vibrato |= 1 << (10 - channel); - OPLWriteReg(_opl, 0xBD, _vibrato); - } -} - -void AdlibSoundDriverADL::playSample(const byte *data, int size, int channel, int volume) { - adjustVolume(channel, 127); - - setupInstrument(data, channel); - AdLibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins->mode != 0 && ins->channel == 6) { - OPLWriteReg(_opl, 0xB0 | channel, 0); - } - if (ins->mode != 0) { - _vibrato &= ~(1 << (10 - ins->channel)); - OPLWriteReg(_opl, 0xBD, _vibrato); - } - if (ins->mode != 0) { - channel = ins->channel; - if (channel == 9) { - channel = 8; - } else if (channel == 10) { - channel = 7; - } - } - uint16 note = 48; - if (ins->amDepth) { - note = ins->amDepth; - } - int freq = _freqTable[note % 12]; - OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); - if (ins->mode == 0) { - freq |= 0x20; - } - OPLWriteReg(_opl, 0xB0 | channel, freq); - if (ins->mode != 0) { - _vibrato |= 1 << (10 - channel); - OPLWriteReg(_opl, 0xBD, _vibrato); - } -} - -/*--------------------------------------------------------------------------*/ - -PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver) - : _playing(false), _songPlayed(false), _driver(driver) { - memset(_instrumentsData, 0, sizeof(_instrumentsData)); - _sfxData = NULL; - _fadeOutCounter = 0; - _driver->setUpdateCallback(updateCallback, this); -} - -PCSoundFxPlayer::~PCSoundFxPlayer() { - _driver->setUpdateCallback(NULL, NULL); - stop(); -} - -bool PCSoundFxPlayer::load(const char *song) { - /* - debug(9, "PCSoundFxPlayer::load('%s')", song); - - // stop (w/ fade out) the previous song - while (_fadeOutCounter != 0 && _fadeOutCounter < 100) { - g_system->delayMillis(50); - } - _fadeOutCounter = 0; - - if (_playing) { - stop(); - } - - strcpy(_musicName, song); - _songPlayed = false; - _looping = false; - _sfxData = readBundleSoundFile(song); - if (!_sfxData) { - warning("Unable to load soundfx module '%s'", song); - return 0; - } - - for (int i = 0; i < NUM_INSTRUMENTS; ++i) { - _instrumentsData[i] = NULL; - - char instrument[64]; - memset(instrument, 0, 64); // Clear the data first - memcpy(instrument, _sfxData + 20 + i * 30, 12); - instrument[63] = '\0'; - - if (strlen(instrument) != 0) { - char *dot = strrchr(instrument, '.'); - if (dot) { - *dot = '\0'; - } - strcat(instrument, _driver->getInstrumentExtension()); - _instrumentsData[i] = readBundleSoundFile(instrument); - if (!_instrumentsData[i]) { - warning("Unable to load soundfx instrument '%s'", instrument); - } - } - } - */ - return 1; -} - -void PCSoundFxPlayer::play() { - debug(9, "PCSoundFxPlayer::play()"); - if (_sfxData) { - for (int i = 0; i < NUM_CHANNELS; ++i) { - _instrumentsChannelTable[i] = -1; - } - _currentPos = 0; - _currentOrder = 0; -// _numOrders = _sfxData[470]; - _eventsDelay = 5; // TODO: What to do with this? - _updateTicksCounter = 0; - _playing = true; - } -} - -void PCSoundFxPlayer::stop() { - if (_playing || _fadeOutCounter != 0) { - _fadeOutCounter = 0; - _playing = false; - for (int i = 0; i < NUM_CHANNELS; ++i) { - _driver->stopChannel(i); - } - _driver->stopAll(); - } - unload(); -} - -void PCSoundFxPlayer::fadeOut() { - if (_playing) { - _fadeOutCounter = 1; - _playing = false; - } -} - -void PCSoundFxPlayer::updateCallback(void *ref) { - ((PCSoundFxPlayer *)ref)->update(); -} - -void PCSoundFxPlayer::update() { - if (_playing || (_fadeOutCounter != 0 && _fadeOutCounter < 100)) { - ++_updateTicksCounter; - if (_updateTicksCounter > _eventsDelay) { - handleEvents(); - _updateTicksCounter = 0; - } - } -} - -void PCSoundFxPlayer::handleEvents() { - const byte *patternData = _sfxData + 600 + 1800; - const byte *orderTable = _sfxData + 472; - uint16 patternNum = orderTable[_currentOrder] * 1024; - - for (int i = 0; i < 4; ++i) { - handlePattern(i, patternData + patternNum + _currentPos); - patternData += 4; - } - - if (_fadeOutCounter != 0 && _fadeOutCounter < 100) { - _fadeOutCounter += 2; - } - if (_fadeOutCounter >= 100) { - stop(); - return; - } - - _currentPos += 16; - if (_currentPos >= 1024) { - _currentPos = 0; - ++_currentOrder; - if (_currentOrder == _numOrders) { - _currentOrder = 0; - } - } - debug(7, "_currentOrder=%d/%d _currentPos=%d", _currentOrder, _numOrders, _currentPos); -} - -void PCSoundFxPlayer::handlePattern(int channel, const byte *patternData) { - int instrument = patternData[2] >> 4; - if (instrument != 0) { - --instrument; - if (_instrumentsChannelTable[channel] != instrument || _fadeOutCounter != 0) { - _instrumentsChannelTable[channel] = instrument; - const int volume = _sfxData[instrument] - _fadeOutCounter; - _driver->setupChannel(channel, _instrumentsData[instrument], instrument, volume); - } - } - int16 freq = (int16)READ_BE_UINT16(patternData); - if (freq > 0) { - _driver->stopChannel(channel); - _driver->setChannelFrequency(channel, freq); - } -} - -void PCSoundFxPlayer::unload() { - for (int i = 0; i < NUM_INSTRUMENTS; ++i) { - free(_instrumentsData[i]); - _instrumentsData[i] = NULL; - } - free(_sfxData); - _sfxData = NULL; - _songPlayed = true; -} - -void PCSoundFxPlayer::doSync(Common::Serializer &s) { - s.syncBytes((byte *)_musicName, 33); - uint16 v = (uint16)songLoaded(); - s.syncAsSint16LE(v); - - if (s.isLoading() && v) { - load(_musicName); - - for (int i = 0; i < NUM_CHANNELS; ++i) { - _instrumentsChannelTable[i] = -1; - } - - _numOrders = _sfxData[470]; - _eventsDelay = (244 - _sfxData[471]) * 100 / 1060; - _updateTicksCounter = 0; - } - - s.syncAsSint16LE(_songPlayed); - s.syncAsSint16LE(_looping); - s.syncAsSint16LE(_currentPos); - s.syncAsSint16LE(_currentOrder); - s.syncAsSint16LE(_playing); -} - -/*--------------------------------------------------------------------------*/ - const byte adlib_group_data[] = { 1, 1, 9, 1, 0xff }; AdlibSoundDriver::AdlibSoundDriver() { @@ -1743,8 +1133,6 @@ AdlibSoundDriver::AdlibSoundDriver() { _groupData.pData = &adlib_group_data[0]; _mixer = _vm->_mixer; - _soundDriver = new AdlibSoundDriverADL(_mixer); - _player = new PCSoundFxPlayer(_soundDriver); } } // End of namespace tSage diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h index 7ad4da5755..e0c550562c 100644 --- a/engines/tsage/sound.h +++ b/engines/tsage/sound.h @@ -44,7 +44,7 @@ struct trackInfoStruct { int _rlbList[SOUND_ARR_SIZE]; int _arr2[SOUND_ARR_SIZE]; byte *_channelData[SOUND_ARR_SIZE]; - int field82[SOUND_ARR_SIZE]; + int _channelNum[SOUND_ARR_SIZE]; int field92[SOUND_ARR_SIZE]; int fielda2[SOUND_ARR_SIZE]; int fieldb2[SOUND_ARR_SIZE]; @@ -341,184 +341,16 @@ public: void release() { _sound.release(); } }; -/*-------------------------------------------------------------------------- - * Adlib related classes - *-------------------------------------------------------------------------- - */ - -struct AdLibRegisterSoundInstrument { - uint8 vibrato; - uint8 attackDecay; - uint8 sustainRelease; - uint8 feedbackStrength; - uint8 keyScaling; - uint8 outputLevel; - uint8 freqMod; -}; - -struct AdLibSoundInstrument { - byte mode; - byte channel; - AdLibRegisterSoundInstrument regMod; - AdLibRegisterSoundInstrument regCar; - byte waveSelectMod; - byte waveSelectCar; - byte amDepth; -}; - -struct VolumeEntry { - int original; - int adjusted; -}; - -class PCSoundDriver { -public: - typedef void (*UpdateCallback)(void *); - - PCSoundDriver() { _upCb = NULL, _upRef = NULL, _musicVolume = 0, _sfxVolume = 0; } - virtual ~PCSoundDriver() {} - - virtual void setupChannel(int channel, const byte *data, int instrument, int volume) = 0; - virtual void setChannelFrequency(int channel, int frequency) = 0; - virtual void stopChannel(int channel) = 0; - virtual void playSample(const byte *data, int size, int channel, int volume) = 0; - virtual void stopAll() = 0; - virtual const char *getInstrumentExtension() const { return ""; } - virtual void syncSounds(); - - void setUpdateCallback(UpdateCallback upCb, void *ref); - void resetChannel(int channel); - void findNote(int freq, int *note, int *oct) const; -protected: - UpdateCallback _upCb; - void *_upRef; - uint8 _musicVolume; - uint8 _sfxVolume; - - static const int _noteTable[]; - static const int _noteTableCount; -}; - -class AdlibDriverBase : public PCSoundDriver, Audio::AudioStream { -public: - AdlibDriverBase(Audio::Mixer *mixer); - virtual ~AdlibDriverBase(); - - // PCSoundDriver interface - virtual void setupChannel(int channel, const byte *data, int instrument, int volume); - virtual void stopChannel(int channel); - virtual void stopAll(); - - // AudioStream interface - virtual int readBuffer(int16 *buffer, const int numSamples); - virtual bool isStereo() const { return false; } - virtual bool endOfData() const { return false; } - virtual int getRate() const { return _sampleRate; } - - void initCard(); - void update(int16 *buf, int len); - void setupInstrument(const byte *data, int channel); - void setupInstrument(const AdLibSoundInstrument *ins, int channel); - void loadRegisterInstrument(const byte *data, AdLibRegisterSoundInstrument *reg); - virtual void loadInstrument(const byte *data, AdLibSoundInstrument *asi) = 0; - virtual void syncSounds(); - - void adjustVolume(int channel, int volume); - -protected: - FM_OPL *_opl; - int _sampleRate; - Audio::Mixer *_mixer; - Audio::SoundHandle _soundHandle; - - byte _vibrato; - VolumeEntry _channelsVolumeTable[10]; - AdLibSoundInstrument _instrumentsTable[10]; - - static const int _freqTable[]; - static const int _freqTableCount; - static const int _operatorsTable[]; - static const int _operatorsTableCount; - static const int _voiceOperatorsTable[]; - static const int _voiceOperatorsTableCount; -}; - -class AdlibSoundDriverADL : public AdlibDriverBase { -public: - AdlibSoundDriverADL(Audio::Mixer *mixer) : AdlibDriverBase(mixer) {} - virtual const char *getInstrumentExtension() const { return ".ADL"; } - virtual void loadInstrument(const byte *data, AdLibSoundInstrument *asi); - virtual void setChannelFrequency(int channel, int frequency); - virtual void playSample(const byte *data, int size, int channel, int volume); -}; - -class PCSoundFxPlayer { -private: - enum { - NUM_INSTRUMENTS = 15, - NUM_CHANNELS = 4 - }; - - void update(); - void handleEvents(); - void handlePattern(int channel, const byte *patternData); - - char _musicName[33]; - bool _playing; - bool _songPlayed; - int _currentPos; - int _currentOrder; - int _numOrders; - int _eventsDelay; - bool _looping; - int _fadeOutCounter; - int _updateTicksCounter; - int _instrumentsChannelTable[NUM_CHANNELS]; - byte *_sfxData; - byte *_instrumentsData[NUM_INSTRUMENTS]; - PCSoundDriver *_driver; - -public: - PCSoundFxPlayer(PCSoundDriver *driver); - ~PCSoundFxPlayer(); - - bool load(const char *song); - void play(); - void stop(); - void unload(); - void fadeOut(); - void doSync(Common::Serializer &s); - - static void updateCallback(void *ref); - - bool songLoaded() const { return _sfxData != NULL; } - bool songPlayed() const { return _songPlayed; } - bool playing() const { return _playing; } - uint8 numOrders() const { assert(_sfxData); return _sfxData[470]; } - void setNumOrders(uint8 v) { assert(_sfxData); _sfxData[470] = v; } - void setPattern(int offset, uint8 value) { assert(_sfxData); _sfxData[472 + offset] = value; } - const char *musicName() { return _musicName; } - - // Note: Original game never actually uses looping variable. Songs are hardcoded to loop - bool looping() const { return _looping; } - void setLooping(bool v) { _looping = v; } -}; - class AdlibSoundDriver: public SoundDriver { private: GroupData _groupData; Audio::Mixer *_mixer; - PCSoundDriver *_soundDriver; - PCSoundFxPlayer *_player; public: AdlibSoundDriver(); virtual void setVolume(int volume) {} virtual void installPatchBank(const byte *data) {} virtual const GroupData *getGroupData() { return &_groupData; } - virtual void play(const byte *data, int size, int channel, int volume) { - _soundDriver->playSample(data, size, channel, volume); - } }; } // End of namespace tSage |