diff options
author | Torbjörn Andersson | 2006-03-17 12:03:24 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2006-03-17 12:03:24 +0000 |
commit | e36edb1b3504165d4aad1c43e10f8722f4283956 (patch) | |
tree | dd5d1c86de222cbed2669110ee6380cbbefdbb51 | |
parent | 9ecd855c2b311d24e9ef885d97df3d54c59e302b (diff) | |
download | scummvm-rg350-e36edb1b3504165d4aad1c43e10f8722f4283956.tar.gz scummvm-rg350-e36edb1b3504165d4aad1c43e10f8722f4283956.tar.bz2 scummvm-rg350-e36edb1b3504165d4aad1c43e10f8722f4283956.zip |
The opcode functions are not allowed to modify their own channel.dataptr
directly. If they want a new data pointer, they have to use the dataptr
parameter. This fixes a subtle bug that would cause the wrong music to play
when getting the quill in Kyra 1.
svn-id: r21344
-rw-r--r-- | engines/kyra/sound_adlib.cpp | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index 90f362a0e6..4d3883931a 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -693,16 +693,26 @@ void AdlibDriver::executePrograms() { if (channel.duration == channel.spacing1 && _curChannel != 9) noteOff(channel); } else { - while (channel.dataptr) { - uint8 opcode = *channel.dataptr++; - uint8 param = *channel.dataptr++; + // An opcode is not allowed to modify its own + // data pointer except through the 'dataptr' + // parameter. To enforce that, we have to work + // on a copy of the data pointer. + // + // This fixes a subtle music bug where the + // wrong music would play when getting the + // quill in Kyra 1. + uint8 *dataptr = channel.dataptr; + while (dataptr) { + uint8 opcode = *dataptr++; + uint8 param = *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); - result = (this->*(_parserOpcodeTable[opcode].function))(channel.dataptr, channel, param); + result = (this->*(_parserOpcodeTable[opcode].function))(dataptr, channel, param); + channel.dataptr = dataptr; if (result) break; } else { @@ -710,8 +720,10 @@ void AdlibDriver::executePrograms() { setupNote(opcode, channel); noteOn(channel); setupDuration(param, channel); - if (param) + if (param) { + channel.dataptr = dataptr; break; + } } } } @@ -1219,6 +1231,7 @@ int AdlibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 va channel2.duration = 1; unkOutput2(chan); } + return 0; } |