aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen/sound_driver.cpp
diff options
context:
space:
mode:
authorPaul Gilbert2018-06-30 10:20:15 -0700
committerPaul Gilbert2018-06-30 10:20:15 -0700
commiteb829a33c91496c516cb7245286c8e1029fd145a (patch)
tree9619480a6b875391269dc3c9e241c27045cc9d62 /engines/xeen/sound_driver.cpp
parente26259d758f3bc948fa6b2571d50a5944d94e9f0 (diff)
downloadscummvm-rg350-eb829a33c91496c516cb7245286c8e1029fd145a.tar.gz
scummvm-rg350-eb829a33c91496c516cb7245286c8e1029fd145a.tar.bz2
scummvm-rg350-eb829a33c91496c516cb7245286c8e1029fd145a.zip
XEEN: Split the Adlib sound driver into it's own file
Diffstat (limited to 'engines/xeen/sound_driver.cpp')
-rw-r--r--engines/xeen/sound_driver.cpp400
1 files changed, 0 insertions, 400 deletions
diff --git a/engines/xeen/sound_driver.cpp b/engines/xeen/sound_driver.cpp
index 967f53ac49..108eba2e5a 100644
--- a/engines/xeen/sound_driver.cpp
+++ b/engines/xeen/sound_driver.cpp
@@ -28,10 +28,6 @@
namespace Xeen {
-#define CALLBACKS_PER_SECOND 73
-
-/*------------------------------------------------------------------------*/
-
SoundDriver::SoundDriver() : _musicPlaying(false), _fxPlaying(false),
_musCountdownTimer(0), _fxCountdownTimer(0), _musDataPtr(nullptr),
_fxDataPtr(nullptr), _fxStartPtr(nullptr), _musStartPtr(nullptr),
@@ -259,400 +255,4 @@ const CommandFn SoundDriver::FX_COMMANDS[16] = {
&SoundDriver::cmdChangeFrequency, &SoundDriver::fxEndSubroutine
};
-/*------------------------------------------------------------------------*/
-
-AdlibSoundDriver::AdlibSoundDriver() : _field180(0), _field181(0), _field182(0),
- _musicVolume(0), _sfxVolume(0) {
- Common::fill(&_musInstrumentPtrs[0], &_musInstrumentPtrs[16], (const byte *)nullptr);
- Common::fill(&_fxInstrumentPtrs[0], &_fxInstrumentPtrs[16], (const byte *)nullptr);
-
- _opl = OPL::Config::create();
- _opl->init();
- _opl->start(new Common::Functor0Mem<void, AdlibSoundDriver>(this, &AdlibSoundDriver::onTimer), CALLBACKS_PER_SECOND);
- initialize();
-}
-
-AdlibSoundDriver::~AdlibSoundDriver() {
- _opl->stop();
- delete _opl;
-}
-
-void AdlibSoundDriver::onTimer() {
- Common::StackLock slock(_driverMutex);
- execute();
- flush();
-}
-
-void AdlibSoundDriver::initialize() {
- write(1, 0x20);
- write(8, 0);
- write(0xBD, 0);
-
- resetFrequencies();
- AdlibSoundDriver::resetFX();
-}
-
-void AdlibSoundDriver::playFX(uint effectId, const byte *data) {
- Common::StackLock slock(_driverMutex);
- SoundDriver::playFX(effectId, data);
-}
-
-void AdlibSoundDriver::playSong(const byte *data) {
- Common::StackLock slock(_driverMutex);
- SoundDriver::playSong(data);
- _field180 = 0;
- resetFrequencies();
-}
-
-int AdlibSoundDriver::songCommand(uint commandId, byte musicVolume, byte sfxVolume) {
- Common::StackLock slock(_driverMutex);
- SoundDriver::songCommand(commandId, musicVolume, sfxVolume);
-
- if (commandId == STOP_SONG) {
- _field180 = 0;
- resetFrequencies();
- } else if (commandId == RESTART_SONG) {
- _field180 = 0;
- _musicPlaying = true;
- } else if (commandId < 0x100) {
- if (_musicPlaying) {
- _field180 = commandId;
- _field182 = 63;
- }
- } else if (commandId == SET_VOLUME) {
- _musicVolume = musicVolume;
- _sfxVolume = sfxVolume;
- } else if (commandId == GET_STATUS) {
- return _field180;
- }
-
- return 0;
-}
-
-void AdlibSoundDriver::write(int reg, int val) {
- _queue.push(RegisterValue(reg, val));
- debugC(9, kDebugSound, "%.2x %.2x", reg, val);
-}
-
-void AdlibSoundDriver::flush() {
- Common::StackLock slock(_driverMutex);
-
- while (!_queue.empty()) {
- RegisterValue v = _queue.pop();
- _opl->writeReg(v._regNum, v._value);
- }
-}
-
-void AdlibSoundDriver::pausePostProcess() {
- if (_field180 && ((_field181 += _field180) < 0)) {
- if (--_field182 < 0) {
- _musicPlaying = false;
- _field180 = 0;
- resetFrequencies();
- } else {
- for (int channelNum = 6; channelNum >= 0; --channelNum) {
- if (_channels[channelNum]._volume < 63)
- setOutputLevel(channelNum, ++_channels[channelNum]._volume);
- }
- }
- }
-
- for (int channelNum = 8; channelNum > (_exclude7 ? 7 : 6); --channelNum) {
- Channel &chan = _channels[channelNum];
- if (!chan._changeFrequency || (chan._freqCtr += chan._freqCtrChange) >= 0)
- continue;
-
- uint freq = chan._frequency & 0x3FF;
- uint val = chan._frequency >> 8;
- byte val1 = val & 0x20;
- byte val2 = val & 0x1C;
-
- freq += chan._freqChange;
- if (chan._freqChange < 0) {
- if (freq <= 388) {
- freq <<= 1;
- if (!(freq & 0x3FF))
- --freq;
- }
-
- val2 = (val2 - 4) & 0x1C;
- } else {
- if (freq >= 734) {
- freq >>= 1;
- if (!(freq & 0x3FF))
- ++freq;
- }
-
- val2 = (val2 + 4) & 0x1C;
- }
-
- freq &= 0x3FF;
- freq |= (val2 << 8);
- freq |= val1;
- chan._frequency = freq;
- setFrequency(channelNum, freq);
- }
-}
-
-void AdlibSoundDriver::resetFX() {
- if (!_exclude7) {
- _channels[7]._frequency = 0;
- setFrequency(7, 0);
- _channels[7]._volume = 63;
- setOutputLevel(7, 63);
- }
-
- _channels[8]._frequency = 0;
- setFrequency(8, 0);
- _channels[8]._volume = 63;
- setOutputLevel(8, 63);
-}
-
-void AdlibSoundDriver::resetFrequencies() {
- for (int opNum = 6; opNum >= 0; --opNum) {
- _channels[opNum]._frequency = 0;
- setFrequency(opNum, 0);
- }
-}
-
-void AdlibSoundDriver::setFrequency(byte operatorNum, uint frequency) {
- write(0xA0 + operatorNum, frequency & 0xff);
- write(0xB0 + operatorNum, (frequency >> 8));
-}
-
-uint AdlibSoundDriver::calcFrequency(byte note) {
- return WAVEFORMS[note & 0x1F] + ((note & 0xE0) << 5);
-}
-
-void AdlibSoundDriver::setOutputLevel(byte channelNum, uint level) {
- write(0x40 + OPERATOR2_INDEXES[channelNum], level |
- (_channels[channelNum]._scalingValue & 0xC0));
-}
-
-void AdlibSoundDriver::playInstrument(byte channelNum, const byte *data, byte volume) {
- byte op1 = OPERATOR1_INDEXES[channelNum];
- byte op2 = OPERATOR2_INDEXES[channelNum];
- debugC(2, kDebugSound, "---START-playInstrument - %d", channelNum);
- write(0x20 + op1, *data++);
- write(0x40 + op1, *data++);
- write(0x60 + op1, *data++);
- write(0x80 + op1, *data++);
- write(0xE0 + op1, *data++);
- write(0x20 + op2, *data++);
-
- int scalingVal = *data++;
- _channels[channelNum]._scalingValue = scalingVal;
- scalingVal += (127 - volume) / 2;
-
- if (scalingVal > 63) {
- scalingVal = 63;
- if (_field180)
- scalingVal = (scalingVal & 0xC0) | _field182;
- }
- write(0x40 + op2, scalingVal);
-
- write(0x60 + op2, *data++);
- write(0x80 + op2, *data++);
- write(0xE0 + op2, *data++);
- write(0xC0 + channelNum, *data++);
-
- debugC(2, kDebugSound, "---END-playInstrument");
-}
-
-bool AdlibSoundDriver::musSetInstrument(const byte *&srcP, byte param) {
- debugC(3, kDebugSound, "musSetInstrument %d", param);
- _musInstrumentPtrs[param] = srcP;
- srcP += 26;
-
- return false;
-}
-
-bool AdlibSoundDriver::musSetPitchWheel(const byte *&srcP, byte param) {
- // Adlib does not support this
- debugC(3, kDebugSound, "musSetPitchWheel");
- srcP += 2;
- return false;
-}
-
-bool AdlibSoundDriver::musSetPanning(const byte *&srcP, byte param) {
- // Adlib does not support this
- debugC(3, kDebugSound, "musSetPanning");
- ++srcP;
- return false;
-}
-
-bool AdlibSoundDriver::musFade(const byte *&srcP, byte param) {
- ++srcP;
- if (param < 7)
- setFrequency(param, _channels[param]._frequency);
- debugC(3, kDebugSound, "musFade");
-
- return false;
-}
-
-bool AdlibSoundDriver::musStartNote(const byte *&srcP, byte param) {
- if (param < 7) {
- byte note = *srcP++;
- ++srcP; // Second byte is fade, which is unused by Adlib
- uint freq = calcFrequency(note);
- debugC(3, kDebugSound, "musStartNote %x -> %x", note, freq);
-
- setFrequency(param, freq);
- freq |= 0x2000;
- _channels[param]._frequency = freq;
- setFrequency(param, freq);
- } else {
- srcP += 2;
- debugC(3, kDebugSound, "musStartNote skipped");
- }
-
- return false;
-}
-
-bool AdlibSoundDriver::musSetVolume(const byte *&srcP, byte param) {
- debugC(3, kDebugSound, "musSetVolume %d", (int)*srcP);
-
- if (*srcP++ == 5 && !_field180) {
- _channels[param]._volume = *srcP;
- setOutputLevel(param, *srcP);
- }
-
- ++srcP;
- return false;
-}
-
-bool AdlibSoundDriver::musInjectMidi(const byte *&srcP, byte param) {
- // Adlib does not support MIDI. So simply keep skipping over bytes
- // until an 'F7' byte is found that flags the end of the MIDI data
- debugC(3, kDebugSound, "musInjectMidi");
- while (*srcP++ != 0xF7)
- ;
-
- return false;
-}
-
-bool AdlibSoundDriver::musPlayInstrument(const byte *&srcP, byte param) {
- byte instrument = *srcP++;
- debugC(3, kDebugSound, "musPlayInstrument %d, %d", param, instrument);
-
- if (param < 7)
- playInstrument(param, _musInstrumentPtrs[instrument], _musicVolume);
-
- return false;
-}
-
-bool AdlibSoundDriver::fxSetInstrument(const byte *&srcP, byte param) {
- debugC(3, kDebugSound, "fxSetInstrument %d", param);
- _fxInstrumentPtrs[param] = srcP;
- srcP += 11;
-
- return false;
-}
-
-bool AdlibSoundDriver::fxSetVolume(const byte *&srcP, byte param) {
- debugC(3, kDebugSound, "fxSetVolume %d", (int)*srcP);
-
- if (!_field180 && (!_exclude7 || param != 7)) {
- _channels[param]._volume = *srcP;
- setOutputLevel(param, *srcP);
- }
-
- ++srcP;
- return false;
-}
-
-bool AdlibSoundDriver::fxMidiReset(const byte *&srcP, byte param) {
- debugC(3, kDebugSound, "fxMidiReset");
- return false;
-}
-
-bool AdlibSoundDriver::fxMidiDword(const byte *&srcP, byte param) {
- debugC(3, kDebugSound, "fxMidiDword");
- return false;
-}
-
-bool AdlibSoundDriver::fxSetPanning(const byte *&srcP, byte param) {
- byte note = *srcP++;
- debugC(3, kDebugSound, "fxSetPanning - %x", note);
-
- if (!_exclude7 || param != 7) {
- uint freq = calcFrequency(note);
- setFrequency(param, freq);
- _channels[param]._frequency = freq;
- }
-
- return false;
-}
-
-bool AdlibSoundDriver::fxChannelOff(const byte *&srcP, byte param) {
- debugC(3, kDebugSound, "fxChannelOff %d", param);
- _channels[param]._frequency &= ~0x2000;
- write(0xB0 + param, _channels[param]._frequency);
- return false;
-}
-
-bool AdlibSoundDriver::fxFade(const byte *&srcP, byte param) {
- uint freq = calcFrequency(*srcP++);
- debugC(3, kDebugSound, "fxFade %d %x", param, freq);
-
- if (!_exclude7 || param != 7) {
- _channels[param]._frequency = freq;
- setFrequency(param, freq);
- }
-
- return false;
-}
-
-bool AdlibSoundDriver::fxStartNote(const byte *&srcP, byte param) {
- if (!_exclude7 || param != 7) {
- byte note = *srcP++;
- uint freq = calcFrequency(note);
- debugC(3, kDebugSound, "fxStartNote %x -> %x", note, freq);
-
- setFrequency(param, freq);
- freq |= 0x2000;
- _channels[param]._frequency = freq;
- setFrequency(param, freq);
- } else {
- ++srcP;
- debugC(3, kDebugSound, "fxStartNote skipped");
- }
-
- return false;
-}
-
-bool AdlibSoundDriver::fxInjectMidi(const byte *&srcP, byte param) {
- // Surpringly, unlike the musInjectMidi, this version doesn't have
- // any logic to skip over following MIDI data. Which must mean the opcode
- // and/or it's data aren't present in the admus driver file
- debugC(3, kDebugSound, "fxInjectMidi");
- return false;
-}
-
-bool AdlibSoundDriver::fxPlayInstrument(const byte *&srcP, byte param) {
- byte instrument = *srcP++;
- debugC(3, kDebugSound, "fxPlayInstrument %d, %d", param, instrument);
-
- if (!_exclude7 || param != 7)
- playInstrument(param, _fxInstrumentPtrs[instrument], _sfxVolume);
-
- return false;
-}
-
-/*------------------------------------------------------------------------*/
-
-const byte AdlibSoundDriver::OPERATOR1_INDEXES[CHANNEL_COUNT] = {
- 0, 1, 2, 8, 9, 0xA, 0x10, 0x11, 0x12
-};
-
-const byte AdlibSoundDriver::OPERATOR2_INDEXES[CHANNEL_COUNT] = {
- 3, 4, 5, 0xB, 0xC, 0xD, 0x13, 0x14, 0x15
-};
-
-const uint AdlibSoundDriver::WAVEFORMS[24] = {
- 0, 347, 388, 436, 462, 519, 582, 646,
- 0, 362, 406, 455, 484, 542, 607, 680,
- 0, 327, 367, 412, 436, 489, 549, 618
-};
-
} // End of namespace Xeen