aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2006-03-17 12:03:24 +0000
committerTorbjörn Andersson2006-03-17 12:03:24 +0000
commite36edb1b3504165d4aad1c43e10f8722f4283956 (patch)
treedd5d1c86de222cbed2669110ee6380cbbefdbb51
parent9ecd855c2b311d24e9ef885d97df3d54c59e302b (diff)
downloadscummvm-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.cpp23
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;
}