From 21337e4cf63fa1c4248bbb2b6173f121a126fed8 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Sun, 24 Sep 2017 01:47:37 -0500 Subject: SCI32: Implement per-channel audio panning Used by RAMA, in various places, starting with the refrigerator at base camp after the cable car at the beginning of the game. --- engines/sci/engine/kernel.h | 2 ++ engines/sci/engine/kernel_tables.h | 4 ++-- engines/sci/engine/ksound.cpp | 10 ++++++++++ engines/sci/sound/audio32.cpp | 21 +++++++++++++++++++++ engines/sci/sound/audio32.h | 10 ++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) (limited to 'engines') diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index a712474983..7e576f5b98 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -440,6 +440,8 @@ reg_t kDoAudioPreload(EngineState *s, int argc, reg_t *argv); reg_t kDoAudioFade(EngineState *s, int argc, reg_t *argv); reg_t kDoAudioHasSignal(EngineState *s, int argc, reg_t *argv); reg_t kDoAudioSetLoop(EngineState *s, int argc, reg_t *argv); +reg_t kDoAudioPan(EngineState *s, int argc, reg_t *argv); +reg_t kDoAudioPanOff(EngineState *s, int argc, reg_t *argv); reg_t kRobot(EngineState *s, int argc, reg_t *argv); reg_t kRobotOpen(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 884a499542..6a45241817 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -236,8 +236,8 @@ static const SciKernelMapSubEntry kDoAudio_subops[] = { { SIG_SINCE_SCI21MID, 17, MAP_CALL(DoAudioHasSignal), "", NULL }, { SIG_SINCE_SCI21MID, 18, MAP_EMPTY(DoAudioCritical), "(i)", NULL }, { SIG_SINCE_SCI21MID, 19, MAP_CALL(DoAudioSetLoop), "iii(o)", NULL }, - { SIG_SCI3, 20, MAP_DUMMY(DoAudioPan), "", NULL }, - { SIG_SCI3, 21, MAP_DUMMY(DoAudioPanOff), "", NULL }, + { SIG_SCI3, 20, MAP_CALL(DoAudioPan), "ii(i)(iii)", NULL }, + { SIG_SCI3, 21, MAP_CALL(DoAudioPanOff), "i(i)(iii)", NULL }, SCI_SUBOPENTRY_TERMINATOR }; #endif diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index ad137566a2..ee4f8efd9a 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -466,6 +466,16 @@ reg_t kDoAudioSetLoop(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +reg_t kDoAudioPan(EngineState *s, int argc, reg_t *argv) { + g_sci->_audio32->kernelPan(argc, argv); + return s->r_acc; +} + +reg_t kDoAudioPanOff(EngineState *s, int argc, reg_t *argv) { + g_sci->_audio32->kernelPanOff(argc, argv); + return s->r_acc; +} + reg_t kSetLanguage(EngineState *s, int argc, reg_t *argv) { // This is used by script 90 of MUMG Deluxe from the main menu to toggle // the audio language between English and Spanish. diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp index 2f30f7dd79..2f7338ea63 100644 --- a/engines/sci/sound/audio32.cpp +++ b/engines/sci/sound/audio32.cpp @@ -1312,6 +1312,27 @@ void Audio32::kernelLoop(const int argc, const reg_t *const argv) { setLoop(channelIndex, loop); } +void Audio32::kernelPan(const int argc, const reg_t *const argv) { + Common::StackLock lock(_mutex); + + const int16 channelIndex = findChannelByArgs(argc, argv, 1, argc == 3 ? argv[2] : NULL_REG); + const int16 pan = argv[0].toSint16(); + if (channelIndex != kNoExistingChannel) { + setPan(channelIndex, pan); + } else { + warning("Attempt to pan a channel that does not exist"); + } +} + +void Audio32::kernelPanOff(const int argc, const reg_t *const argv) { + Common::StackLock lock(_mutex); + + const int16 channelIndex = findChannelByArgs(argc, argv, 0, argc == 2 ? argv[1] : NULL_REG); + if (channelIndex != kNoExistingChannel) { + setPan(channelIndex, -1); + } +} + #pragma mark - #pragma mark Debugging diff --git a/engines/sci/sound/audio32.h b/engines/sci/sound/audio32.h index 8b8ec2a6b5..71f5883541 100644 --- a/engines/sci/sound/audio32.h +++ b/engines/sci/sound/audio32.h @@ -508,6 +508,14 @@ public: setLoop(findChannelById(resourceId, soundNode), loop); } + /** + * Sets the stereo panning for the given channel. + */ + void setPan(const int16 channelIndex, const int16 pan) { + Common::StackLock lock(_mutex); + getChannel(channelIndex).pan = pan; + } + private: /** * The tick when audio was globally paused. @@ -644,6 +652,8 @@ public: reg_t kernelMixing(const int argc, const reg_t *const argv); reg_t kernelFade(const int argc, const reg_t *const argv); void kernelLoop(const int argc, const reg_t *const argv); + void kernelPan(const int argc, const reg_t *const argv); + void kernelPanOff(const int argc, const reg_t *const argv); #pragma mark - #pragma mark Debugging -- cgit v1.2.3