aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/sound/soundcmd.cpp23
1 files changed, 12 insertions, 11 deletions
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 9f3deca8ff..b0102a002b 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -530,20 +530,21 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
}
reg_t SoundCommandParser::kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc) {
+ // The 4 parameter variant of this call is used in at least LSL1VGA, room
+ // 110 (Lefty's bar), to distort the music when Larry is drunk and stands
+ // up - bug #3614447.
reg_t obj = argv[0];
byte channel = argv[1].toUint16() & 0xf;
- byte midiCmd = argv[2].toUint16() & 0xff;
-
- // TODO: There is a 4 parameter variant of this call,
- // used by at least lsl1vga.
- // It lacks a midiCmd argument, but for this variant midiCmd defaults to
- // 0xB0 (controller). If argv[2] is 0xFF, midiCmd is 0xE0
- // (pitchwheel). The exact parameters need to be investigated further.
- if (argc == 4)
- return acc;
+ byte midiCmd = (argc == 5) ? argv[2].toUint16() & 0xff : 0xB0; // 0xB0: controller
+ uint16 controller = (argc == 5) ? argv[3].toUint16() : argv[2].toUint16();
+ uint16 param = (argc == 5) ? argv[4].toUint16() : argv[3].toUint16();
- uint16 controller = argv[3].toUint16();
- uint16 param = argv[4].toUint16();
+ if (argc == 4 && controller == 0xFF) {
+ midiCmd = 0xE0; // 0xE0: pitch wheel
+ uint16 pitch = CLIP<uint16>(argv[3].toSint16() + 0x2000, 0x0000, 0x3FFF);
+ controller = pitch & 0x7F;
+ param = pitch >> 7;
+ }
debugC(kDebugLevelSound, "kDoSound(sendMidi): %04x:%04x, %d, %d, %d, %d", PRINT_REG(obj), channel, midiCmd, controller, param);
if (channel)