diff options
-rw-r--r-- | engines/kyra/sound_adlib.cpp | 69 |
1 files changed, 31 insertions, 38 deletions
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index e36e4c6e70..a567c7dce3 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -326,7 +326,6 @@ private: int _soundsPlaying; uint16 _rnd; - uint8 _continueFlag; uint8 _unkValue1; uint8 _unkValue2; @@ -393,7 +392,6 @@ AdlibDriver::AdlibDriver(Audio::Mixer *mixer) { _lastProcessed = _flagTrigger = _curChannel = _unk4 = 0; _rnd = 0x1234; - _continueFlag = 0; _tempo = 0; @@ -649,16 +647,14 @@ void AdlibDriver::callbackOutput() { // opcode that doesn't have that one parameter is responsible for moving the // data pointer back again. // -// If the most significant bit of the opcode is 1, it's a function; call it. If -// it returns something greater than zero, it's the last opcode in the current -// set of opcodes. An opcode can also make itself the last one by setting the -// data pointer to NULL. +// If the most significant bit of the opcode is 1, it's a function; call it. +// The opcode functions return either 0 (continue), 1 (stop) or 2 (stop, and do +// not run the effects callbacks). // // If the most significant bit of the opcode is 0, it's a note, and the first // parameter is its duration. (There are cases where the duration is modified -// but that's an exception.) This duration is also assigned to _continueFlag, -// which affects the return value from several of the opcode functions. If the -// duration is non-zero, it's the last opcode in the current set of opcodes. +// but that's an exception.) The note opcode is assumed to return 1, and is the +// last opcode unless its duration is zero. // // Finally, most of the times that the callback is called, it will invoke the // effects callbacks. The final opcode in a set can prevent this, if it's a @@ -666,6 +662,8 @@ void AdlibDriver::callbackOutput() { void AdlibDriver::callbackProcess() { for (_curChannel = 9; _curChannel >= 0; --_curChannel) { + int result = 1; + if (!_channels[_curChannel].dataptr) { continue; } @@ -686,40 +684,36 @@ void AdlibDriver::callbackProcess() { if (channel.duration == channel.unk3 && _curChannel != 9) noteOff(channel); } else { - int8 opcode = 0; while (channel.dataptr) { - uint16 command = READ_LE_UINT16(channel.dataptr); - channel.dataptr += 2; - if (command & 0x0080) { - opcode = command & 0x7F; - if (opcode > 0x4A) - opcode = 0x4A; + uint8 opcode = *channel.dataptr++; + uint8 param = *channel.dataptr++; + + if (opcode & 0x80) { + opcode &= 0x7F; + if (opcode >= _parserOpcodeTableSize) + opcode = _parserOpcodeTableSize - 1; debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d) (channel: %d)", _parserOpcodeTable[opcode].name, opcode, _curChannel); - opcode = (this->*(_parserOpcodeTable[opcode].function))(channel.dataptr, channel, (command & 0xFF00) >> 8); - --opcode; - if (opcode >= 0) + result = (this->*(_parserOpcodeTable[opcode].function))(channel.dataptr, channel, param); + if (result) break; - continue; } else { - debugC(9, kDebugLevelSound, "Note on opcode 0x%02X (duration: %d) (channel: %d)", command & 0xFF, (command >> 8) & 0xFF, _curChannel); - opcode = 0; - setupNote(command & 0xFF, channel); + debugC(9, kDebugLevelSound, "Note on opcode 0x%02X (duration: %d) (channel: %d)", opcode, param, _curChannel); + setupNote(opcode, channel); noteOn(channel); - setupDuration((command & 0xFF00) >> 8, channel); - if (!_continueFlag) - continue; - break; + setupDuration(param, channel); + if (param) + break; } } - if (opcode) - continue; } } - if (channel.primaryEffect) - (this->*(channel.primaryEffect))(channel); - if (channel.secondaryEffect) - (this->*(channel.secondaryEffect))(channel); + if (result == 1) { + if (channel.primaryEffect) + (this->*(channel.primaryEffect))(channel); + if (channel.secondaryEffect) + (this->*(channel.secondaryEffect))(channel); + } } } @@ -830,7 +824,6 @@ uint16 AdlibDriver::getRandomNr() { void AdlibDriver::setupDuration(uint8 duration, Channel &channel) { debugC(9, kDebugLevelSound, "setupDuration(%d, %d)", duration, &channel - _channels); - _continueFlag = duration; if (channel.unk11) { channel.duration = duration + (getRandomNr() & channel.unk11); return; @@ -1257,7 +1250,7 @@ int AdlibDriver::updateCallback9(uint8 *&dataptr, Channel &channel, uint8 value) int AdlibDriver::update_playRest(uint8 *&dataptr, Channel &channel, uint8 value) { setupDuration(value, channel); noteOff(channel); - return (_continueFlag != 0); + return (value != 0); } int AdlibDriver::update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value) { @@ -1269,7 +1262,7 @@ int AdlibDriver::updateCallback12(uint8 *&dataptr, Channel &channel, uint8 value setupNote(value, channel); value = *dataptr++; setupDuration(value, channel); - return (_continueFlag != 0); + return (value != 0); } int AdlibDriver::update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value) { @@ -1383,13 +1376,13 @@ int AdlibDriver::update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 int AdlibDriver::updateCallback26(uint8 *&dataptr, Channel &channel, uint8 value) { setupDuration(value, channel); - return (_continueFlag != 0); + return (value != 0); } int AdlibDriver::update_playNote(uint8 *&dataptr, Channel &channel, uint8 value) { setupDuration(value, channel); noteOn(channel); - return (_continueFlag != 0); + return (value != 0); } int AdlibDriver::updateCallback28(uint8 *&dataptr, Channel &channel, uint8 value) { |