[Scummvm-git-logs] scummvm master -> e815605b1bab62779765f6de4006bd2b3291fb93
NMIError
noreply at scummvm.org
Sun Aug 16 15:11:45 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
ab9ac1f19a MADS: Move MT-32 driver to sound manager and improve Channel naming
e815605b1b MADS: Fixes for Rex MT-32 sound driver
Commit: ab9ac1f19abc54b59c86b42df04b1436e571103f
https://github.com/scummvm/scummvm/commit/ab9ac1f19abc54b59c86b42df04b1436e571103f
Author: Coen Rampen (crampen at gmail.com)
Date: 2026-08-16T16:49:59+02:00
Commit Message:
MADS: Move MT-32 driver to sound manager and improve Channel naming
Changed paths:
engines/mads/core/sound_manager.cpp
engines/mads/core/sound_manager.h
engines/mads/nebular/sound/rsound.cpp
engines/mads/nebular/sound/rsound.h
engines/mads/nebular/sound/rsound_nebular.cpp
engines/mads/nebular/sound/rsound_nebular.h
engines/mads/nebular/sound/sound.cpp
diff --git a/engines/mads/core/sound_manager.cpp b/engines/mads/core/sound_manager.cpp
index cc3525c1eff..0155a3d52a6 100644
--- a/engines/mads/core/sound_manager.cpp
+++ b/engines/mads/core/sound_manager.cpp
@@ -33,8 +33,14 @@ class Mixer;
namespace MADS {
-SoundManager::SoundManager(Audio::Mixer *mixer, bool &soundFlag,
+ const uint32 SoundManager::UPDATE_DELTA = 1000000 / 60;
+
+ SoundManager::SoundManager(Audio::Mixer *mixer, bool &soundFlag,
bool supportsGeneralMidi) : _mixer(mixer), _soundFlag(soundFlag) {
+ _updateDeltaRemainder = 0;
+ _driverCallbackDelta = 0;
+ _midiDriver = nullptr;
+
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32);
MusicType musicType = MidiDriver::getMusicType(dev);
if ((musicType == MT_GM || musicType == MT_GS) && ConfMan.getBool("native_mt32"))
@@ -42,6 +48,15 @@ SoundManager::SoundManager(Audio::Mixer *mixer, bool &soundFlag,
switch (musicType) {
case MT_MT32:
_driverType = SOUND_MT32;
+ _midiDriver = new MidiDriver_MT32GM(MusicType::MT_MT32);
+ int returnCode;
+ returnCode = _midiDriver->open();
+ if (returnCode != 0)
+ error("RSound - Failed to open MIDI music driver - error code %d.", returnCode);
+
+ _driverCallbackDelta = _midiDriver->getBaseTempo();
+ _midiDriver->setTimerCallback(this, &timerCallback);
+
break;
case MT_GM:
case MT_GS:
@@ -57,9 +72,21 @@ SoundManager::SoundManager(Audio::Mixer *mixer, bool &soundFlag,
}
SoundManager::~SoundManager() {
- if (_driver) {
+ if (_driver != nullptr) {
_driver->stop();
+ }
+ if (_midiDriver != nullptr) {
+ _midiDriver->setTimerCallback(nullptr, nullptr);
+ _midiDriver->close();
+ }
+
+ if (_driver != nullptr) {
delete _driver;
+ _driver = nullptr;
+ }
+ if (_midiDriver != nullptr) {
+ delete _midiDriver;
+ _midiDriver = nullptr;
}
}
@@ -144,6 +171,23 @@ void SoundManager::noise() {
_driver->noise();
}
+void SoundManager::onTimer() {
+ // The frequency of the callbacks is dependent on the underlying driver
+ // implementation and might not be 60Hz. Adjust to make sure poll() is called
+ // with the correct frequency.
+ _updateDeltaRemainder += _driverCallbackDelta;
+ while (_updateDeltaRemainder >= UPDATE_DELTA) {
+ if (_driver)
+ _driver->poll();
+ _updateDeltaRemainder -= UPDATE_DELTA;
+ }
+}
+
+void SoundManager::timerCallback(void *data) {
+ SoundManager *soundManager = (SoundManager *)data;
+ soundManager->onTimer();
+}
+
//====================================================================
SoundDriver::SoundDriver(Audio::Mixer *mixer, const Common::Path &filename,
diff --git a/engines/mads/core/sound_manager.h b/engines/mads/core/sound_manager.h
index c48aaea47ce..22d47028219 100644
--- a/engines/mads/core/sound_manager.h
+++ b/engines/mads/core/sound_manager.h
@@ -22,6 +22,7 @@
#ifndef MADS_CORE_SOUND_MANAGER_H
#define MADS_CORE_SOUND_MANAGER_H
+#include "audio/mt32gm.h"
#include "common/array.h"
#include "common/memstream.h"
#include "common/mutex.h"
@@ -98,9 +99,16 @@ protected:
int _param;
};
+ // Number of microseconds between driver updates (60 Hz frequency)
+ static const uint32 UPDATE_DELTA;
+
enum DriverType { SOUND_ADLIB, SOUND_MT32, SOUND_GM, SOUND_PCSPEAKER, SOUND_PAS };
Audio::Mixer *_mixer;
DriverType _driverType;
+ MidiDriver_MT32GM *_midiDriver;
+ uint32 _driverCallbackDelta;
+ uint32 _updateDeltaRemainder;
+
bool &_soundFlag;
SoundDriver *_driver = nullptr;
bool _newSoundsPaused = false;
@@ -193,6 +201,9 @@ public:
void noise();
//@}
+
+ void onTimer();
+ static void timerCallback(void *data);
};
} // namespace MADS
diff --git a/engines/mads/nebular/sound/rsound.cpp b/engines/mads/nebular/sound/rsound.cpp
index 2c2ef48c2d8..1df08cb7bc2 100644
--- a/engines/mads/nebular/sound/rsound.cpp
+++ b/engines/mads/nebular/sound/rsound.cpp
@@ -29,46 +29,45 @@ namespace MADS {
namespace RexNebular {
namespace Sound {
-void Channel::reset(byte *startPtr) {
- _pitchBendFadeStep = 0;
- _panFadeStep = 0;
- _innerLoopCount = 0;
- _outerLoopCount = 0;
- _noteOffset = 0;
- _pendingStop = 0;
- _volumeFadeReload = 0xFF;
+void Channel::loadData(byte *soundData) {
+ _pitchSlideStepSize = 0;
+ _panningSweepStepSize = 0;
+ _innerLoopCounter = 0;
+ _outerLoopCounter = 0;
+ _noteDurationOffset = 0;
+ _fadeOutActive = 0;
+ _volumeFadeSpeed = 0xFF;
_pitchBend = 64;
- _pan = 64;
- _loopStartPtr = startPtr;
- _pSrc = startPtr;
- _innerLoopPtr = startPtr;
- _outerLoopPtr = startPtr;
- _soundData = startPtr;
+ _panning = 64;
+ _soundDataStart = soundData;
+ _pSrc = soundData;
+ _innerLoopStart = soundData;
+ _outerLoopStart = soundData;
+ _soundData = soundData;
}
-void Channel::enable(int flag) {
- if (_activeCount) {
- _pendingStop = flag;
+void Channel::setFadeOut(bool fadeOut) {
+ if (_deltaCounter) {
+ _fadeOutActive = fadeOut;
// WORKAROUND: matches the same apparent original-code quirk
- // documented in AdlibChannel::enable() - the original set
+ // documented in AdlibChannel::setFadeOut() - the original set
// _soundData to the flag value here, which we replace with
// a simple null pointer.
_soundData = nullptr;
}
}
-void Channel::load(byte *pData) {
- reset(pData);
- _activeCount = 1;
+void Channel::playData(byte *soundData) {
+ loadData(soundData);
+ _deltaCounter = 1;
_owner->sendPitchBend(_midiChannel, 0x40);
}
/*-----------------------------------------------------------------------*/
-RSound::RSound(Audio::Mixer *mixer, const Common::Path &filename,
- int dataOffset, int dataSize, int sysExOffset,
- RSoundFadeCheckMode fadeCheckMode) :
+RSound::RSound(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver, const Common::Path &filename,
+ int dataOffset, int dataSize, int sysExOffset, RSoundFadeCheckMode fadeCheckMode) :
SoundDriver(mixer, filename, dataOffset, dataSize) {
_commandParam = 0;
_frameCounter = 0;
@@ -80,6 +79,7 @@ RSound::RSound(Audio::Mixer *mixer, const Common::Path &filename,
_pollResult = 0;
_resultFlag = 0;
_sysExOffset = sysExOffset;
+ _midiDriver = midiDriver;
_fadeCheckMode = fadeCheckMode;
_fadeCheckAlternate = false;
_fadeCheckCounter = 0;
@@ -90,13 +90,6 @@ RSound::RSound(Audio::Mixer *mixer, const Common::Path &filename,
_channels[i]._midiChannel = i + 1;
}
- _midiDriver = new MidiDriver_MT32GM(MusicType::MT_MT32);
- int returnCode = _midiDriver->open();
- if (returnCode != 0)
- error("RSound - Failed to open MIDI music driver - error code %d.", returnCode);
-
- _driverCallbackDelta = _midiDriver->getBaseTempo();
-
// rsound_init calls resetAllChannels directly, then later
// (via initDeviceOnce, on successful hardware detection) calls
// rsound_command0, which resets the channels again and sends the
@@ -109,21 +102,9 @@ RSound::RSound(Audio::Mixer *mixer, const Common::Path &filename,
// nothing to guard against.
command0();
sendSysExSequence();
-
- _midiDriver->setTimerCallback(this, &timerCallback);
}
RSound::~RSound() {
- _isDisabled = true;
- if (_midiDriver != nullptr) {
- _midiDriver->setTimerCallback(nullptr, nullptr);
- _midiDriver->close();
-
- Common::StackLock lock(_driverMutex);
-
- delete _midiDriver;
- _midiDriver = nullptr;
- }
}
void RSound::validate(bool isDemo) {
@@ -169,6 +150,8 @@ int RSound::stop() {
}
int RSound::poll() {
+ Common::StackLock slock(_driverMutex);
+
update();
int result = _pollResult;
@@ -195,16 +178,16 @@ Channel *RSound::playSoundData(byte *pData, int startingChannel) {
// Scan for a free channel
for (int i = startingChannel; i < endChannel; ++i) {
- if (!_channels[i]._activeCount) {
- _channels[i].load(pData);
+ if (!_channels[i]._deltaCounter) {
+ _channels[i].playData(pData);
return &_channels[i];
}
}
// None found; fall back to an interruptable (pending-stop) channel
for (int i = endChannel - 1; i >= startingChannel; --i) {
- if (_channels[i]._pendingStop == 0xFF) {
- _channels[i].load(pData);
+ if (_channels[i]._fadeOutActive) {
+ _channels[i].playData(pData);
return &_channels[i];
}
}
@@ -216,7 +199,7 @@ bool RSound::isSoundActive(byte *pData) {
// Deliberately excludes channel 9 (index 8), matching the disassembly -
// same as playSoundData()'s scan never reaching channel 9 either.
for (int i = 0; i < RSOUND_CHANNEL_COUNT - 1; ++i) {
- if (_channels[i]._activeCount && _channels[i]._soundData == pData)
+ if (_channels[i]._deltaCounter && _channels[i]._soundData == pData)
return true;
}
@@ -229,22 +212,6 @@ int RSound::getRandomNumber() {
return _randomSeed;
}
-void RSound::onTimer() {
- Common::StackLock slock(_driverMutex);
-
- uint32 serviceTicks = _hostTimer.advance(_driverCallbackDelta, 1000000);
- while (serviceTicks--) {
- // RSOUND export 4 is a return stub in every audited overlay.
- if (_hostTimer.pollDue())
- poll();
- }
-}
-
-void RSound::timerCallback(void* data) {
- RSound *rsound = (RSound *)data;
- rsound->onTimer();
-}
-
void RSound::setVolume(int volume) {
_masterVolume = CLIP(volume, 0, 255);
for (int i = 0; i < RSOUND_CHANNEL_COUNT; ++i)
@@ -355,9 +322,9 @@ void RSound::Channel_flushHeldNotes(Channel *channel) {
}
void RSound::Channel_checkFade(Channel *channel) {
- if (!channel->_activeCount)
+ if (!channel->_deltaCounter)
return;
- if (!channel->_pendingStop)
+ if (!channel->_fadeOutActive)
return;
if (channel->_volume != 0) {
@@ -366,13 +333,13 @@ void RSound::Channel_checkFade(Channel *channel) {
} else {
// Fully silent - recycle the channel to a fixed 2-byte (0,0)
// silence stream. pollActiveChannel() processing a (note=0,
- // duration=0) pair sets _activeCount to 0, and its own
+ // duration=0) pair sets _deltaCounter to 0, and its own
// top-of-function guard (checked before any decrement) then
// short-circuits every later call before _pSrc is ever read
// again - so only these first 2 bytes are ever consumed.
static byte silenceStream[2] = { 0, 0 };
channel->_pSrc = silenceStream;
- channel->_pendingStop = 0;
+ channel->_fadeOutActive = false;
}
}
@@ -395,15 +362,15 @@ void RSound::checkFadingChannels() {
}
void RSound::Channel_pollActive(Channel *channel) {
- if (!channel->_activeCount)
+ if (!channel->_deltaCounter)
return;
int midiChannel = channel->_midiChannel;
- if (channel->_keyOnDelay > 0 && --channel->_keyOnDelay == 0)
+ if (channel->_noteDurationCounter > 0 && --channel->_noteDurationCounter == 0)
Channel_flushHeldNotes(channel);
- if (--channel->_activeCount <= 0) {
+ if (--channel->_deltaCounter <= 0) {
for (;;) {
byte *pSrc = channel->_pSrc;
@@ -418,16 +385,16 @@ void RSound::Channel_pollActive(Channel *channel) {
byte note = pSrc[0];
byte duration = pSrc[1];
channel->_note = note;
- channel->_activeCount = duration;
+ channel->_deltaCounter = duration;
channel->_pSrc = pSrc + 2;
if (!note || !duration) {
Channel_flushHeldNotes(channel);
} else {
- channel->_keyOnDelay = channel->_activeCount - channel->_noteOffset;
+ channel->_noteDurationCounter = channel->_deltaCounter - channel->_noteDurationOffset;
bool skipRetrigger = false;
- if ((int8)channel->_noteOffset < 0 && _heldNotes[midiChannel][0] == note)
+ if ((int8)channel->_noteDurationOffset < 0 && _heldNotes[midiChannel][0] == note)
skipRetrigger = true;
if (!skipRetrigger) {
@@ -459,15 +426,15 @@ void RSound::Channel_pollActive(Channel *channel) {
}
case 2: // 0xF3: setup pan fade
- channel->_panFadeReload = pSrc[1];
- channel->_panFadeStep = pSrc[2];
- channel->_panFadeCounter = 1;
+ channel->_panningSweepSpeed = pSrc[1];
+ channel->_panningSweepStepSize = pSrc[2];
+ channel->_panningSweepCounter = 1;
channel->_pSrc = pSrc + 3;
break;
case 3: // 0xF4: set pan directly and send
- channel->_pan = pSrc[1];
- sendPan(midiChannel, channel->_pan);
+ channel->_panning = pSrc[1];
+ sendPan(midiChannel, channel->_panning);
channel->_pSrc = pSrc + 2;
break;
@@ -488,12 +455,12 @@ void RSound::Channel_pollActive(Channel *channel) {
slots[i] = 0xFF;
byte duration = notes[noteCount];
- channel->_activeCount = duration;
- if (channel->_noteOffset != 0xFF) {
- channel->_keyOnDelay = (duration < channel->_noteOffset) ?
- duration : duration - channel->_noteOffset;
+ channel->_deltaCounter = duration;
+ if (channel->_noteDurationOffset != 0xFF) {
+ channel->_noteDurationCounter = (duration < channel->_noteDurationOffset) ?
+ duration : duration - channel->_noteDurationOffset;
} else {
- channel->_keyOnDelay = duration + 1;
+ channel->_noteDurationCounter = duration + 1;
}
channel->_pSrc = pSrc + noteCount + 3;
@@ -502,7 +469,7 @@ void RSound::Channel_pollActive(Channel *channel) {
}
case 5: // 0xF6: set volume directly and send (priority-gated while pending-stop)
- if (!channel->_pendingStop || channel->_volume >= pSrc[1]) {
+ if (!channel->_fadeOutActive || channel->_volume >= pSrc[1]) {
channel->_volume = pSrc[1];
sendVolume(midiChannel, channel->_volume);
}
@@ -516,10 +483,10 @@ void RSound::Channel_pollActive(Channel *channel) {
break;
case 7: // 0xF8: setup volume fade (gated by pending-stop)
- if (!channel->_pendingStop) {
- channel->_volumeFadeReload = pSrc[1];
+ if (!channel->_fadeOutActive) {
+ channel->_volumeFadeSpeed = pSrc[1];
channel->_volumeFadeCounter = pSrc[1];
- channel->_volumeFadeStep = pSrc[2];
+ channel->_volumeFadeStepSize = pSrc[2];
}
channel->_pSrc = pSrc + 3;
break;
@@ -530,15 +497,15 @@ void RSound::Channel_pollActive(Channel *channel) {
break;
case 9: // 0xFA: setup pitch-bend ramp
- channel->_pitchBendFadeReload = pSrc[1];
- channel->_pitchBendFadeStep = pSrc[2];
- channel->_pitchBendFadeCount = pSrc[3];
- channel->_pitchBendFadeCounter = 1;
+ channel->_pitchSlideSpeed = pSrc[1];
+ channel->_pitchSlideStepSize = pSrc[2];
+ channel->_pitchSlideDurationCounter = pSrc[3];
+ channel->_pitchSlideCounter = 1;
channel->_pSrc = pSrc + 4;
break;
case 10: // 0xFB: set note offset
- channel->_noteOffset = pSrc[1];
+ channel->_noteDurationOffset = pSrc[1];
channel->_pSrc = pSrc + 2;
break;
@@ -549,52 +516,52 @@ void RSound::Channel_pollActive(Channel *channel) {
break;
case 12: { // 0xFD: full reset / loop restart, preserving pending-stop
- int pendingStop = channel->_pendingStop;
- channel->reset(channel->_loopStartPtr);
- channel->_pendingStop = pendingStop;
+ bool fadeOutActive = channel->_fadeOutActive;
+ channel->loadData(channel->_soundDataStart);
+ channel->_fadeOutActive = fadeOutActive;
break;
}
case 13: // 0xFE: outer loop
- if (!channel->_outerLoopCount) {
+ if (!channel->_outerLoopCounter) {
if (*++pSrc == 0) {
channel->_pSrc += 2;
- channel->_outerLoopPtr = channel->_pSrc;
- channel->_innerLoopPtr = channel->_pSrc;
- channel->_innerLoopCount = 0;
- channel->_outerLoopCount = 0;
+ channel->_outerLoopStart = channel->_pSrc;
+ channel->_innerLoopStart = channel->_pSrc;
+ channel->_innerLoopCounter = 0;
+ channel->_outerLoopCounter = 0;
} else {
- channel->_outerLoopCount =
- (uint16)(int16)(int8)*pSrc;
- channel->_pSrc = channel->_outerLoopPtr;
- channel->_innerLoopPtr = channel->_outerLoopPtr;
+ channel->_outerLoopCounter =
+ (uint16)(int16)(int8)*pSrc;
+ channel->_pSrc = channel->_outerLoopStart;
+ channel->_innerLoopStart = channel->_outerLoopStart;
}
- } else if (--channel->_outerLoopCount) {
- channel->_pSrc = channel->_outerLoopPtr;
- channel->_innerLoopPtr = channel->_outerLoopPtr;
+ } else if (--channel->_outerLoopCounter) {
+ channel->_pSrc = channel->_outerLoopStart;
+ channel->_innerLoopStart = channel->_outerLoopStart;
} else {
channel->_pSrc += 2;
- channel->_outerLoopPtr = channel->_pSrc;
- channel->_innerLoopPtr = channel->_pSrc;
+ channel->_outerLoopStart = channel->_pSrc;
+ channel->_innerLoopStart = channel->_pSrc;
}
break;
case 14: // 0xFF: inner loop
- if (!channel->_innerLoopCount) {
+ if (!channel->_innerLoopCounter) {
if (*++pSrc == 0) {
channel->_pSrc += 2;
- channel->_innerLoopPtr = channel->_pSrc;
- channel->_innerLoopCount = 0;
+ channel->_innerLoopStart = channel->_pSrc;
+ channel->_innerLoopCounter = 0;
} else {
- channel->_innerLoopCount =
- (uint16)(int16)(int8)*pSrc;
- channel->_pSrc = channel->_innerLoopPtr;
+ channel->_innerLoopCounter =
+ (uint16)(int16)(int8)*pSrc;
+ channel->_pSrc = channel->_innerLoopStart;
}
- } else if (--channel->_innerLoopCount) {
- channel->_pSrc = channel->_innerLoopPtr;
+ } else if (--channel->_innerLoopCounter) {
+ channel->_pSrc = channel->_innerLoopStart;
} else {
channel->_pSrc += 2;
- channel->_innerLoopPtr = channel->_pSrc;
+ channel->_innerLoopStart = channel->_pSrc;
}
break;
@@ -605,25 +572,25 @@ void RSound::Channel_pollActive(Channel *channel) {
}
// Fade tail: pitch bend, volume, pan
- if (channel->_pitchBendFadeStep) {
- if (!--channel->_pitchBendFadeCounter) {
- channel->_pitchBendFadeCounter = channel->_pitchBendFadeReload;
- channel->_pitchBend += channel->_pitchBendFadeStep;
+ if (channel->_pitchSlideStepSize) {
+ if (!--channel->_pitchSlideCounter) {
+ channel->_pitchSlideCounter = channel->_pitchSlideSpeed;
+ channel->_pitchBend += channel->_pitchSlideStepSize;
sendPitchBend(midiChannel, channel->_pitchBend);
}
- if (!--channel->_pitchBendFadeCount)
- channel->_pitchBendFadeStep = 0;
+ if (!--channel->_pitchSlideDurationCounter)
+ channel->_pitchSlideStepSize = 0;
}
- if (channel->_volumeFadeStep) {
+ if (channel->_volumeFadeStepSize) {
if (!--channel->_volumeFadeCounter) {
- channel->_volumeFadeCounter = channel->_volumeFadeReload;
- int8 newVolume = (int8)channel->_volume + (int8)channel->_volumeFadeStep;
+ channel->_volumeFadeCounter = channel->_volumeFadeSpeed;
+ int8 newVolume = (int8)channel->_volume + (int8)channel->_volumeFadeStepSize;
if (newVolume < 0) {
- channel->_volumeFadeStep = 0;
+ channel->_volumeFadeStepSize = 0;
newVolume = 0;
} else if (newVolume >= 0x7F) {
- channel->_volumeFadeStep = 0;
+ channel->_volumeFadeStepSize = 0;
newVolume = 0x7F;
}
channel->_volume = newVolume;
@@ -631,15 +598,15 @@ void RSound::Channel_pollActive(Channel *channel) {
}
}
- if (channel->_panFadeStep) {
- if (!--channel->_panFadeCounter) {
- channel->_panFadeCounter = channel->_panFadeReload;
- byte newPan = channel->_pan + channel->_panFadeStep;
+ if (channel->_panningSweepStepSize) {
+ if (!--channel->_panningSweepCounter) {
+ channel->_panningSweepCounter = channel->_panningSweepSpeed;
+ byte newPan = channel->_panning + channel->_panningSweepStepSize;
if (newPan > 0x7F) {
newPan = (newPan ^ 0x7F) & 0x7F;
- channel->_panFadeCounter = 0;
+ channel->_panningSweepCounter = 0;
}
- channel->_pan = newPan;
+ channel->_panning = newPan;
sendPan(midiChannel, newPan);
}
}
@@ -665,7 +632,7 @@ void RSound::update() {
/*-----------------------------------------------------------------------*/
/**
- * Zeroes _activeCount and the three fade-step fields for channels in
+ * Zeroes _deltaCounter and the three fade-step fields for channels in
* [first, last).
* Deliberately does NOT touch the loop pointers, volume, program, pan etc,
* matching the original.
@@ -675,10 +642,10 @@ void RSound::resetChannelRange(int first, int last) {
_isDisabled = true;
for (int i = first; i < last; ++i) {
- _channels[i]._activeCount = 0;
- _channels[i]._pitchBendFadeStep = 0;
- _channels[i]._volumeFadeStep = 0;
- _channels[i]._panFadeStep = 0;
+ _channels[i]._deltaCounter = 0;
+ _channels[i]._pitchSlideStepSize = 0;
+ _channels[i]._volumeFadeStepSize = 0;
+ _channels[i]._panningSweepStepSize = 0;
}
_isDisabled = wasDisabled;
@@ -744,7 +711,7 @@ int RSound::command0() {
int RSound::command1() {
setFadeCheckPeriod(1);
for (int i = 0; i < RSOUND_CHANNEL_COUNT; ++i)
- _channels[i].enable(0xFF);
+ _channels[i].setFadeOut(true);
return 0;
}
@@ -761,7 +728,7 @@ int RSound::command2() {
int RSound::command3() {
setFadeCheckPeriod(1);
for (int i = 0; i < 5; ++i)
- _channels[i].enable(0xFF);
+ _channels[i].setFadeOut(true);
return 0;
}
@@ -777,7 +744,7 @@ int RSound::command4() {
int RSound::command5() {
setFadeCheckPeriod(1);
for (int i = 5; i < RSOUND_CHANNEL_COUNT; ++i)
- _channels[i].enable(0xFF);
+ _channels[i].setFadeOut(true);
return 0;
}
@@ -796,7 +763,7 @@ int RSound::command7() {
int RSound::command8() {
int result = 0;
for (int i = 0; i < RSOUND_CHANNEL_COUNT; ++i)
- result |= _channels[i]._activeCount;
+ result |= _channels[i]._deltaCounter;
return result;
}
diff --git a/engines/mads/nebular/sound/rsound.h b/engines/mads/nebular/sound/rsound.h
index c62a1a4dfca..fb3c0e3fe59 100644
--- a/engines/mads/nebular/sound/rsound.h
+++ b/engines/mads/nebular/sound/rsound.h
@@ -48,20 +48,20 @@ enum RSoundFadeCheckMode {
* equivalent AdlibChannel fields in asound.h.
*
* Confirmed against the real DOS struct layout (IDA struct dump,
- * sizeof=0x22): every field below from _activeCount through _soundData
+ * sizeof=0x22): every field below from _deltaCounter through _soundData
* matches the original both in name and in byte offset/order exactly:
- * 0x00 _activeCount 0x0C _volume 0x18 _innerLoopPtr
- * 0x01 _pitchBendFadeStep 0x0D _pitchBend 0x1A _outerLoopPtr
- * 0x02 _volumeFadeStep 0x0E _pan 0x1C _innerLoopCount
- * 0x03 _panFadeStep 0x0F _volumeFadeReload 0x1E _outerLoopCount
- * 0x04 _note 0x10 _pitchBendFadeReload 0x20 _soundData
- * 0x05 _program 0x11 _panFadeReload
- * 0x06 _velocity 0x12 _pitchBendFadeCount
- * 0x07 _noteOffset 0x13 _pendingStop
- * 0x08 _keyOnDelay 0x14 _loopStartPtr
- * 0x09 _volumeFadeCounter 0x16 _pSrc
- * 0x0A _pitchBendFadeCounter
- * 0x0B _panFadeCounter
+ * 0x00 _deltaCounter 0x0C _volume 0x18 _innerLoopStart
+ * 0x01 _pitchSlideStepSize 0x0D _pitchBend 0x1A _outerLoopStart
+ * 0x02 _volumeFadeStepSize 0x0E _panning 0x1C _innerLoopCounter
+ * 0x03 _panningSweepStepSize 0x0F _volumeFadeSpeed 0x1E _outerLoopCounter
+ * 0x04 _note 0x10 _pitchSlideSpeed 0x20 _soundData
+ * 0x05 _program 0x11 _panningSweepSpeed
+ * 0x06 _velocity 0x12 _pitchSlideDurationCounter
+ * 0x07 _noteDurationOffset 0x13 _fadeOutActive
+ * 0x08 _noteDurationCounter 0x14 _soundDataStart
+ * 0x09 _volumeFadeCounter 0x16 _pSrc
+ * 0x0A _pitchSlideCounter
+ * 0x0B _panningSweepCounter
* _owner and _midiChannel below are NOT part of the original struct (it
* has no equivalent fields) - they're C++-side conveniences so Channel
* methods and callers don't need the MIDI channel number (array index+1)
@@ -71,57 +71,61 @@ enum RSoundFadeCheckMode {
class Channel {
public:
RSound *_owner = nullptr;
- int _midiChannel = 0; // 1-9: the MIDI channel this struct drives
-
- int _activeCount = 0; // gate/duration countdown; also freshly loaded from the duration byte of a note event
- int _pitchBendFadeStep = 0; // per-step delta added to _pitchBend each ramp tick
- int _volumeFadeStep = 0; // per-step delta added to _volume each ramp tick
- int _panFadeStep = 0; // per-step delta added to _pan each ramp tick
- int _note = 0; // MIDI note number, read from the note/duration stream
- int _program = 0; // patch/instrument number, sent as a Program Change
- int _velocity = 0; // note velocity, used by RSound::sendNoteOn()
- int _noteOffset = 0; // subtracted from _activeCount to derive _keyOnDelay; 0xFF = sustain full duration +1 (no early cutoff)
- int _keyOnDelay = 0; // countdown to RSound::Channel_flushHeldNotes()
- int _volumeFadeCounter = 0; // counts down to 0 before applying _volumeFadeStep
- int _pitchBendFadeCounter = 0; // counts down to 0 before applying _pitchBendFadeStep
- int _panFadeCounter = 0; // counts down to 0 before applying _panFadeStep
- int _volume = 0; // current channel volume (MIDI CC#7)
- int _pitchBend = 0; // current pitch bend value (status 0xEn, coarse/MSB only)
- int _pan = 0; // current pan value (MIDI CC#10); 64 = center
- int _volumeFadeReload = 0; // reload value for _volumeFadeCounter
- int _pitchBendFadeReload = 0; // reload value for _pitchBendFadeCounter
- int _panFadeReload = 0; // reload value for _panFadeCounter
- int _pitchBendFadeCount = 0; // total ramp steps remaining before the pitch-bend ramp halts
- int _pendingStop = 0; // non-zero while the channel is fading out to silence
- byte *_loopStartPtr = nullptr; // fixed restart anchor used by the full-reset/loop-restart opcode
- byte *_pSrc = nullptr; // current read pointer into the sound-data stream
- byte *_innerLoopPtr = nullptr; // inner-loop restart address
- byte *_outerLoopPtr = nullptr; // outer-loop restart address
- uint16 _innerLoopCount = 0; // signed byte stored as a 16-bit loop count
- uint16 _outerLoopCount = 0; // signed byte stored as a 16-bit loop count
- byte *_soundData = nullptr; // identity pointer used by RSound::isSoundActive()
+ int _midiChannel = 0; // 1-9: the MIDI channel to which the data in this struct pertains
+
+ int _deltaCounter = 0; // number of ticks until the next event occurs; loaded from the delta byte of a note or chord event
+ // 0: channel is not active
+ int _pitchSlideStepSize = 0; // delta added to _pitchBend each pitch-slide step; 0: pitch slide is not active
+ int _volumeFadeStepSize = 0; // delta added to _volume each volume fade step; 0: volume fade is not active
+ int _panningSweepStepSize = 0; // delta added to _panning each panning sweep step; 0: panning sweep is not active
+ int _note = 0; // MIDI note number, read from the note or chord event
+ int _program = 0; // patch/instrument number, sent as a Program Change
+ int _velocity = 0; // note velocity, used by RSound::sendNoteOn()
+ int _noteDurationOffset = 0; // subtracted from the event delta to derive the note duration; positive offset: note is turned off
+ // before the next event is processed. Data might only use up to -1 in the negative direction.
+ int _noteDurationCounter = 0; // number of ticks until the currently active note(s) is/are turned off
+ int _volumeFadeCounter = 0; // number of ticks until the next volume fade step is processed
+ int _pitchSlideCounter = 0; // number of ticks until the next pitch slide step is processed
+ int _panningSweepCounter = 0; // number of ticks until the next panning sweep step is processed
+ int _volume = 0; // current channel volume (MIDI CC#7)
+ int _pitchBend = 0; // current pitch bend value (status 0xEn, coarse/MSB only); 0x40 = center
+ int _panning = 0; // current pan value (MIDI CC#10); 0x40 = center
+ int _volumeFadeSpeed = 0; // number of ticks between volume fade steps
+ int _pitchSlideSpeed = 0; // number of ticks between pitch slide steps
+ int _panningSweepSpeed = 0; // number of ticks between panning sweep steps
+ int _pitchSlideDurationCounter = 0; // number of ticks until the pitch slide ends
+ bool _fadeOutActive = false; // true while the channel is fading out to silence (not to be confused with a volume fade)
+ byte *_soundDataStart = nullptr; // start of the sound data stream playing on this channel
+ byte *_pSrc = nullptr; // current read pointer into the sound data stream
+ byte *_innerLoopStart = nullptr; // inner loop restart address
+ byte *_outerLoopStart = nullptr; // outer loop restart address
+ int _innerLoopCounter = 0; // number of repeats of the inner loop remaining
+ int _outerLoopCounter = 0; // number of repeats of the outer loop remaining
+ byte *_soundData = nullptr; // identifies the sound data played by this channel; effectively the same as _soundDataStart
public:
Channel() {}
/**
- * Partial reset used both when loading a new sound and when the
- * loop-restart opcode fires. Deliberately does NOT touch volume,
- * program, velocity, key-on state or active/duration - matches
- * Channel_reset() in the original disassembly.
+ * Resets most of the channel data to its default values and loads
+ * the specified sound data into the channel. Deliberately does NOT
+ * touch volume, program, velocity, key-on state or delta/duration -
+ * matches the original disassembly.
*/
- void reset(byte *startPtr);
+ void loadData(byte *soundData);
/**
- * Marks the channel as pending-stop (fading toward silence).
+ * Marks the channel as fading out (fading toward silence) and stopping
+ * playback when the fade-out is complete. Not to be confused with a
+ * volume fade triggered by event 0xF8.
*/
- void enable(int flag);
+ void setFadeOut(bool fadeOut);
/**
- * Loads a brand new sound into the channel: resets it, marks it
- * active, and resets pitch bend to center on the real device.
+ * Loads new sound data into the channel, starts playback by setting
+ * _deltaCounter to 1 and resets pitch bend to center on the MT-32.
*/
- void load(byte *pData);
+ void playData(byte *soundData);
};
/**
@@ -163,10 +167,6 @@ private:
void pollAllChannels();
void Channel_pollActive(Channel *channel);
- /**
- * Zeroes _activeCount and the three fade-step fields for channels in
- * [first, last).
- */
/**
* Resets all 9 channels and the held-notes table.
*/
@@ -323,9 +323,8 @@ public:
* @param sysExOffset Offset of this driver's own command0_array
* @param fadeCheckMode Native pending-stop fade scheduler
*/
- RSound(Audio::Mixer *mixer, const Common::Path &filename,
- int dataOffset, int dataSize, int sysExOffset,
- RSoundFadeCheckMode fadeCheckMode);
+ RSound(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver, const Common::Path &filename,
+ int dataOffset, int dataSize, int sysExOffset, RSoundFadeCheckMode fadeCheckMode);
~RSound() override;
@@ -339,9 +338,6 @@ public:
int getFrameCounter() {
return _frameCounter;
}
-
- void onTimer();
- static void timerCallback(void *data);
};
} // namespace Sound
diff --git a/engines/mads/nebular/sound/rsound_nebular.cpp b/engines/mads/nebular/sound/rsound_nebular.cpp
index dd93a28af30..cb31b8234f3 100644
--- a/engines/mads/nebular/sound/rsound_nebular.cpp
+++ b/engines/mads/nebular/sound/rsound_nebular.cpp
@@ -25,17 +25,17 @@ namespace MADS {
namespace RexNebular {
namespace Sound {
-RSoundDemo::RSoundDemo(Audio::Mixer *mixer, const Common::Path &filename,
+RSoundDemo::RSoundDemo(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver, const Common::Path &filename,
int dataOffset, int dataSize, int sysExOffset,
int firstEffectChannel) :
- RSound(mixer, filename, dataOffset, dataSize, sysExOffset,
+ RSound(mixer, midiDriver, filename, dataOffset, dataSize, sysExOffset,
kRSoundFadeCheckAlternating),
_firstEffectChannel(firstEffectChannel) {
}
void RSoundDemo::startVoice(int channelIndex, int sequenceOffset) {
assert(channelIndex >= 0 && channelIndex < RSOUND_CHANNEL_COUNT);
- _channels[channelIndex].load(loadData(sequenceOffset));
+ _channels[channelIndex].playData(loadData(sequenceOffset));
}
int RSoundDemo::startVoiceInRange(int sequenceOffset, int firstChannel,
@@ -43,14 +43,14 @@ int RSoundDemo::startVoiceInRange(int sequenceOffset, int firstChannel,
assert(firstChannel >= 0 && firstChannel <= lastChannel && lastChannel < 8);
for (int channel = firstChannel; channel <= lastChannel; ++channel) {
- if (!_channels[channel]._activeCount) {
+ if (!_channels[channel]._deltaCounter) {
startVoice(channel, sequenceOffset);
return channel;
}
}
for (int channel = lastChannel; channel >= firstChannel; --channel) {
- if (_channels[channel]._pendingStop == 0xFF) {
+ if (_channels[channel]._fadeOutActive) {
startVoice(channel, sequenceOffset);
return channel;
}
@@ -73,7 +73,7 @@ void RSoundDemo::requestStopRange(int firstChannel, int channelCount) {
firstChannel + channelCount <= RSOUND_CHANNEL_COUNT);
for (int channel = firstChannel;
channel < firstChannel + channelCount; ++channel)
- _channels[channel].enable(0xFF);
+ _channels[channel].setFadeOut(true);
}
void RSoundDemo::requestStopAll() {
@@ -112,8 +112,8 @@ const RSound1::CommandPtr RSound1::_commandList[42] = {
&RSound1::command40, &RSound1::command41
};
-RSound1::RSound1(Audio::Mixer *mixer) : RSound(mixer, "rsound.001",
- 0x1350, 0x1A90, 0x67, kRSoundFadeCheckAlternating) {
+RSound1::RSound1(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.001", 0x1350, 0x1A90, 0x67, kRSoundFadeCheckAlternating) {
}
int RSound1::command(int commandId, int param) {
@@ -133,10 +133,10 @@ void RSound1::method1() {
byte *pData = loadData(0x1166);
if (!isSoundActive(pData)) {
command1();
- _channels[0].load(pData);
- _channels[1].load(loadData(0x13BC));
- _channels[2].load(loadData(0x155C));
- _channels[3].load(loadData(0x15D8));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x13BC));
+ _channels[2].playData(loadData(0x155C));
+ _channels[3].playData(loadData(0x15D8));
}
}
@@ -148,10 +148,10 @@ int RSound1::command9() {
int RSound1::command10() {
byte *pData = loadData(0xCE4);
if (!isSoundActive(pData)) {
- _channels[0].load(pData);
- _channels[1].load(loadData(0xD18));
- _channels[2].load(loadData(0xE9C));
- _channels[3].load(loadData(0xEE8));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0xD18));
+ _channels[2].playData(loadData(0xE9C));
+ _channels[3].playData(loadData(0xEE8));
}
return 0;
}
@@ -192,9 +192,9 @@ int RSound1::command15() {
byte *pData = loadData(0xF3A);
if (!isSoundActive(pData)) {
command1();
- _channels[4].load(pData);
- _channels[5].load(loadData(0x102A));
- _channels[6].load(loadData(0x110E));
+ _channels[4].playData(pData);
+ _channels[5].playData(loadData(0x102A));
+ _channels[6].playData(loadData(0x110E));
}
return 0;
}
@@ -258,7 +258,7 @@ int RSound1::command26() {
pData[8] = v1;
int v2 = clampParam() + 64;
pData[5] = v2;
- _channels[7].load(pData);
+ _channels[7].playData(pData);
return 0;
}
@@ -268,7 +268,7 @@ int RSound1::command27() {
pData[8] = v1;
int v2 = clampParam() + 64;
pData[5] = v2;
- _channels[7].load(pData);
+ _channels[7].playData(pData);
return 0;
}
@@ -355,11 +355,11 @@ int RSound1::command38() {
int RSound1::command39() {
byte *pData = loadData(0x1818);
if (!isSoundActive(pData)) {
- _channels[4].load(pData);
- _channels[5].load(loadData(0x1848));
- _channels[6].load(loadData(0x1874));
- _channels[7].load(loadData(0x18B4));
- _channels[8].load(loadData(0x18CE));
+ _channels[4].playData(pData);
+ _channels[5].playData(loadData(0x1848));
+ _channels[6].playData(loadData(0x1874));
+ _channels[7].playData(loadData(0x18B4));
+ _channels[8].playData(loadData(0x18CE));
}
return 0;
}
@@ -376,8 +376,8 @@ int RSound1::command41() {
/*-----------------------------------------------------------------------*/
-RSoundDemo1::RSoundDemo1(Audio::Mixer *mixer) :
- RSoundDemo(mixer, "rsound.001", 0x12E0, 0x1D28, 0x67, 0),
+RSoundDemo1::RSoundDemo1(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSoundDemo(mixer, midiDriver, "rsound.001", 0x12E0, 0x1D28, 0x67, 0),
_command23Toggle(false) {
}
@@ -609,8 +609,8 @@ const RSound2::CommandPtr RSound2::_commandList[44] = {
&RSound2::command40, &RSound2::command41, &RSound2::command42, &RSound2::command43
};
-RSound2::RSound2(Audio::Mixer *mixer) : RSound(mixer, "rsound.002",
- 0x1390, 0x42F0, 0x87, kRSoundFadeCheckAlternating) {
+RSound2::RSound2(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.002", 0x1390, 0x42F0, 0x87, kRSoundFadeCheckAlternating) {
}
int RSound2::command(int commandId, int param) {
@@ -624,11 +624,11 @@ int RSound2::command(int commandId, int param) {
int RSound2::command5() {
_pitchCycleCounter = 47;
- _channels[3].enable(0xFF);
- _channels[4].enable(0xFF);
- _channels[5].enable(0xFF);
- _channels[6].enable(0xFF);
- _channels[7].enable(0xFF);
+ _channels[3].setFadeOut(true);
+ _channels[4].setFadeOut(true);
+ _channels[5].setFadeOut(true);
+ _channels[6].setFadeOut(true);
+ _channels[7].setFadeOut(true);
return 0;
}
@@ -636,9 +636,9 @@ int RSound2::command9() {
byte *pData = loadData(0x103C);
if (!isSoundActive(pData)) {
command1();
- _channels[0].load(pData);
- _channels[1].load(loadData(0x11B2));
- _channels[8].load(loadData(0x127E));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x11B2));
+ _channels[8].playData(loadData(0x127E));
}
return 0;
}
@@ -647,8 +647,8 @@ int RSound2::command10() {
byte *pData = loadData(0x132E);
if (!isSoundActive(pData)) {
command1();
- _channels[2].load(pData);
- _channels[8].load(loadData(0x1384));
+ _channels[2].playData(pData);
+ _channels[8].playData(loadData(0x1384));
}
return 0;
}
@@ -657,8 +657,8 @@ int RSound2::command11() {
byte *pData = loadData(0x1548);
if (!isSoundActive(pData)) {
command1();
- _channels[2].load(pData);
- _channels[8].load(loadData(0x1648));
+ _channels[2].playData(pData);
+ _channels[8].playData(loadData(0x1648));
}
return 0;
}
@@ -690,7 +690,7 @@ int RSound2::command15() {
playSoundAny(0x1DFC);
playSoundAny(0x222E);
playSoundAny(0x2648);
- _channels[8].load(loadData(0x26A2));
+ _channels[8].playData(loadData(0x26A2));
}
return 0;
}
@@ -721,11 +721,11 @@ int RSound2::command17() {
}
int RSound2::command18() {
- if (_channels[7]._activeCount)
+ if (_channels[7]._deltaCounter)
return 0;
int idx = (getRandomNumber() & 30) >> 1;
- _channels[7].load(loadData(_table1[idx]));
+ _channels[7].playData(loadData(_table1[idx]));
return 0;
}
@@ -784,11 +784,11 @@ int RSound2::command26() {
int RSound2::command27() {
Channel *ch = playSound(0xFAC);
if (ch)
- ch->_innerLoopPtr = loadData(0xFB8);
+ ch->_innerLoopStart = loadData(0xFB8);
ch = playSound(0xFB2);
if (ch)
- ch->_innerLoopPtr = loadData(0xFB8);
+ ch->_innerLoopStart = loadData(0xFB8);
playSound(0xFB8);
return 0;
@@ -919,8 +919,8 @@ const RSound3::CommandPtr RSound3::_commandList[61] = {
&RSound3::command60
};
-RSound3::RSound3(Audio::Mixer *mixer) : RSound(mixer, "rsound.003",
- 0x14E0, 0x4C60, 0x67, kRSoundFadeCheckProgrammable) {
+RSound3::RSound3(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.003", 0x14E0, 0x4C60, 0x67, kRSoundFadeCheckProgrammable) {
}
int RSound3::command(int commandId, int param) {
@@ -940,10 +940,10 @@ Channel *RSound3::method1(int offset, byte value) {
void RSound3::resetUpperChannelsTail() {
setFadeCheckPeriod(1);
- _channels[4].enable(0xFF);
- _channels[5].enable(0xFF);
- _channels[6].enable(0xFF);
- _channels[7].enable(0xFF);
+ _channels[4].setFadeOut(true);
+ _channels[5].setFadeOut(true);
+ _channels[6].setFadeOut(true);
+ _channels[7].setFadeOut(true);
}
int RSound3::command1() {
@@ -973,11 +973,11 @@ int RSound3::command10() {
byte *pData = loadData(0x14FE);
if (!isSoundActive(pData)) {
command1();
- _channels[0].load(pData);
- _channels[1].load(loadData(0x1630));
- _channels[2].load(loadData(0x186E));
- _channels[3].load(loadData(0x1A68));
- _channels[8].load(loadData(0x1AA6));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x1630));
+ _channels[2].playData(loadData(0x186E));
+ _channels[3].playData(loadData(0x1A68));
+ _channels[8].playData(loadData(0x1AA6));
}
return 0;
}
@@ -992,13 +992,13 @@ void RSound3::setVariantByte(byte value) {
int RSound3::command11() {
if (!isSoundActive(loadData(0x1AE6))) {
setVariantByte(0x64);
- _channels[0].load(loadData(0x1AE6));
- _channels[1].load(loadData(0x1E00));
- _channels[2].load(loadData(0x1E66));
- _channels[3].load(loadData(0x204A));
- _channels[4].load(loadData(0x229C));
- _channels[5].load(loadData(0x2748));
- _channels[6].load(loadData(0x2C56));
+ _channels[0].playData(loadData(0x1AE6));
+ _channels[1].playData(loadData(0x1E00));
+ _channels[2].playData(loadData(0x1E66));
+ _channels[3].playData(loadData(0x204A));
+ _channels[4].playData(loadData(0x229C));
+ _channels[5].playData(loadData(0x2748));
+ _channels[6].playData(loadData(0x2C56));
}
return 0;
}
@@ -1014,14 +1014,14 @@ int RSound3::command13() {
}
int RSound3::command14() {
- _channels[0].load(loadData(0x32DC));
- _channels[1].load(loadData(0x32FC));
- _channels[2].load(loadData(0x331C));
- _channels[3].load(loadData(0x333E));
- _channels[4].load(loadData(0x335C));
- _channels[5].load(loadData(0x339E));
- _channels[6].load(loadData(0x33DE));
- _channels[7].load(loadData(0x341E));
+ _channels[0].playData(loadData(0x32DC));
+ _channels[1].playData(loadData(0x32FC));
+ _channels[2].playData(loadData(0x331C));
+ _channels[3].playData(loadData(0x333E));
+ _channels[4].playData(loadData(0x335C));
+ _channels[5].playData(loadData(0x339E));
+ _channels[6].playData(loadData(0x33DE));
+ _channels[7].playData(loadData(0x341E));
return 0;
}
@@ -1036,20 +1036,20 @@ int RSound3::command15() {
setVariantByte(0x60);
sendDualVolume(0x60);
- if (_channels[3]._activeCount && _channels[3]._soundData == loadData(0x204A)) {
- _channels[2]._pendingStop = 0xFF;
- _channels[3]._pendingStop = 0xFF;
- _channels[4]._pendingStop = 0xFF;
- _channels[5]._pendingStop = 0xFF;
- _channels[6]._pendingStop = 0xFF;
- _channels[7]._pendingStop = 0xFF;
+ if (_channels[3]._deltaCounter && _channels[3]._soundData == loadData(0x204A)) {
+ _channels[2]._fadeOutActive = true;
+ _channels[3]._fadeOutActive = true;
+ _channels[4]._fadeOutActive = true;
+ _channels[5]._fadeOutActive = true;
+ _channels[6]._fadeOutActive = true;
+ _channels[7]._fadeOutActive = true;
setFadeCheckPeriod(1);
return 0;
}
command1();
- _channels[0].load(loadData(0x1AE6));
- _channels[1].load(loadData(0x1E00));
+ _channels[0].playData(loadData(0x1AE6));
+ _channels[1].playData(loadData(0x1E00));
return 0;
}
@@ -1059,19 +1059,19 @@ int RSound3::command16() {
if (_command16AltFlag) {
byte *pData = loadData(0x345E);
if (!isSoundActive(pData)) {
- _channels[0].load(pData);
- _channels[1].load(loadData(0x364C));
- _channels[2].load(loadData(0x3806));
- _channels[3].load(loadData(0x399E));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x364C));
+ _channels[2].playData(loadData(0x3806));
+ _channels[3].playData(loadData(0x399E));
}
} else {
byte *pData = loadData(0x3B26);
if (!isSoundActive(pData)) {
command1();
- _channels[0].load(pData);
- _channels[1].load(loadData(0x3BD8));
- _channels[2].load(loadData(0x3CF8));
- _channels[3].load(loadData(0x3E46));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x3BD8));
+ _channels[2].playData(loadData(0x3CF8));
+ _channels[3].playData(loadData(0x3E46));
}
}
return 0;
@@ -1081,22 +1081,22 @@ int RSound3::command17() {
byte *pData = loadData(0x3F5C);
if (!isSoundActive(pData)) {
command1();
- _channels[0].load(pData);
- _channels[1].load(loadData(0x4022));
- _channels[2].load(loadData(0x41F0));
- _channels[3].load(loadData(0x42F8));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x4022));
+ _channels[2].playData(loadData(0x41F0));
+ _channels[3].playData(loadData(0x42F8));
}
return 0;
}
int RSound3::command18() {
command1();
- _channels[0].load(loadData(0x4492));
- _channels[1].load(loadData(0x45A4));
- _channels[2].load(loadData(0x46A2));
- _channels[3].load(loadData(0x47DC));
- _channels[4].load(loadData(0x49C0));
- _channels[5].load(loadData(0x4A4E));
+ _channels[0].playData(loadData(0x4492));
+ _channels[1].playData(loadData(0x45A4));
+ _channels[2].playData(loadData(0x46A2));
+ _channels[3].playData(loadData(0x47DC));
+ _channels[4].playData(loadData(0x49C0));
+ _channels[5].playData(loadData(0x4A4E));
return 0;
}
@@ -1323,8 +1323,8 @@ const RSound4::CommandPtr RSound4::_commandList[60] = {
&RSound4::command56, &RSound4::command57, &RSound4::command58, &RSound4::command59
};
-RSound4::RSound4(Audio::Mixer *mixer) : RSound(mixer, "rsound.004",
- 0x1340, 0x2E20, 0x67, kRSoundFadeCheckProgrammable) {
+RSound4::RSound4(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.004", 0x1340, 0x2E20, 0x67, kRSoundFadeCheckProgrammable) {
}
int RSound4::command(int commandId, int param) {
@@ -1367,31 +1367,31 @@ void RSound4::setCommand12Variant() {
}
int RSound4::command12() {
- if (_channels[4]._soundData == loadData(0x1966) && _channels[4]._activeCount) {
+ if (_channels[4]._soundData == loadData(0x1966) && _channels[4]._deltaCounter) {
setCommand12Variant();
return 0;
}
setCommand12Variant();
command1();
- _channels[4].load(loadData(0x1966));
- _channels[5].load(loadData(0x1DC8));
- _channels[6].load(loadData(0x1FBA));
- _channels[7].load(loadData(0x211E));
- _channels[8].load(loadData(0x24A8));
+ _channels[4].playData(loadData(0x1966));
+ _channels[5].playData(loadData(0x1DC8));
+ _channels[6].playData(loadData(0x1FBA));
+ _channels[7].playData(loadData(0x211E));
+ _channels[8].playData(loadData(0x24A8));
return 0;
}
void RSound4::loadIntroChannels() {
- _channels[0].load(loadData(0x1274));
- _channels[1].load(loadData(0x13A6));
- _channels[2].load(loadData(0x15E4));
+ _channels[0].playData(loadData(0x1274));
+ _channels[1].playData(loadData(0x13A6));
+ _channels[2].playData(loadData(0x15E4));
}
int RSound4::command10() {
command1();
- _channels[3].load(loadData(0x17DE));
- _channels[8].load(loadData(0x181C));
+ _channels[3].playData(loadData(0x17DE));
+ _channels[8].playData(loadData(0x181C));
loadIntroChannels();
return 0;
}
@@ -1458,7 +1458,7 @@ int RSound4::command52() {
_channels[0]._pSrc = loadData(0x1188);
_channels[1]._pSrc = loadData(0x1188);
_channels[2]._pSrc = loadData(0x1188);
- _channels[4].load(loadData(0x2A0C));
+ _channels[4].playData(loadData(0x2A0C));
return 0;
}
@@ -1534,8 +1534,8 @@ const RSound5::CommandPtr RSound5::_commandList[42] = {
&RSound5::command40, &RSound5::command41
};
-RSound5::RSound5(Audio::Mixer *mixer) : RSound(mixer, "rsound.005",
- 0x12A0, 0x1FD0, 0x67, kRSoundFadeCheckProgrammable) {
+RSound5::RSound5(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.005", 0x12A0, 0x1FD0, 0x67, kRSoundFadeCheckProgrammable) {
}
int RSound5::command(int commandId, int param) {
@@ -1574,16 +1574,16 @@ int RSound5::command13() {
}
int RSound5::command14() {
- _channels[7].load(loadData(0x1272));
+ _channels[7].playData(loadData(0x1272));
return 0;
}
int RSound5::command15() {
if (_channels[7]._soundData == loadData(0x1272)) {
byte *pData = loadData(0x1288);
- _channels[7]._innerLoopPtr = pData;
- _channels[7]._outerLoopPtr = pData;
- _channels[7]._activeCount = 1;
+ _channels[7]._innerLoopStart = pData;
+ _channels[7]._outerLoopStart = pData;
+ _channels[7]._deltaCounter = 1;
}
return 0;
}
@@ -1653,17 +1653,17 @@ int RSound5::command28() {
}
void RSound5::loadTailChannels() {
- _channels[3].load(loadData(0x1688));
- _channels[8].load(loadData(0x1882));
+ _channels[3].playData(loadData(0x1688));
+ _channels[8].playData(loadData(0x1882));
}
int RSound5::command29() {
byte *pData = loadData(0x1488);
if (!isSoundActive(pData)) {
command1();
- _channels[0].load(pData);
- _channels[1].load(loadData(0x1534));
- _channels[2].load(loadData(0x15EA));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x1534));
+ _channels[2].playData(loadData(0x15EA));
loadTailChannels();
}
return 0;
@@ -1730,7 +1730,7 @@ int RSound5::command40() {
int RSound5::command41() {
_channels[8]._pSrc = loadData(0x1182);
- _channels[3].load(loadData(0x1BB6));
+ _channels[3].playData(loadData(0x1BB6));
return 0;
}
@@ -1747,8 +1747,8 @@ const RSound6::CommandPtr RSound6::_commandList[30] = {
&RSound6::nullCommand, &RSound6::command28
};
-RSound6::RSound6(Audio::Mixer *mixer) : RSound(mixer, "rsound.006",
- 0x12D0, 0x1EF0, 0x67, kRSoundFadeCheckProgrammable) {
+RSound6::RSound6(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.006", 0x12D0, 0x1EF0, 0x67, kRSoundFadeCheckProgrammable) {
}
int RSound6::command(int commandId, int param) {
@@ -1776,9 +1776,9 @@ void RSound6::reloadCommand24() {
command1();
_callbackCounter = 84;
_callbackPeriod = 84;
- _channels[0].load(loadData(0x1A38));
- _channels[1].load(loadData(0x1BBE));
- _channels[8].load(loadData(0x1B90));
+ _channels[0].playData(loadData(0x1A38));
+ _channels[1].playData(loadData(0x1BBE));
+ _channels[8].playData(loadData(0x1B90));
}
void RSound6::reloadCommand28() {
@@ -1786,11 +1786,11 @@ void RSound6::reloadCommand28() {
command1();
_callbackCounter = 84;
_callbackPeriod = 84;
- _channels[0].load(loadData(0x130A));
- _channels[1].load(loadData(0x13B6));
- _channels[2].load(loadData(0x146C));
- _channels[3].load(loadData(0x150A));
- _channels[8].load(loadData(0x1704));
+ _channels[0].playData(loadData(0x130A));
+ _channels[1].playData(loadData(0x13B6));
+ _channels[2].playData(loadData(0x146C));
+ _channels[3].playData(loadData(0x150A));
+ _channels[8].playData(loadData(0x1704));
}
int RSound6::command9() {
@@ -1858,7 +1858,7 @@ int RSound6::command20() {
}
int RSound6::command21() {
- _channels[4].load(loadData(0x1282));
+ _channels[4].playData(loadData(0x1282));
playSound(0x1282);
playSound(0x1282);
playSound(0x12AA);
@@ -1866,10 +1866,10 @@ int RSound6::command21() {
}
int RSound6::command22() {
- _channels[4].load(loadData(0x12CE));
- _channels[5].load(loadData(0x12CE));
- _channels[6].load(loadData(0x12CE));
- _channels[7].load(loadData(0x12CE));
+ _channels[4].playData(loadData(0x12CE));
+ _channels[5].playData(loadData(0x12CE));
+ _channels[6].playData(loadData(0x12CE));
+ _channels[7].playData(loadData(0x12CE));
return 0;
}
@@ -1879,7 +1879,7 @@ int RSound6::command23() {
}
int RSound6::command24() {
- if (_channels[0]._activeCount && _channels[0]._soundData == loadData(0x130A)) {
+ if (_channels[0]._deltaCounter && _channels[0]._soundData == loadData(0x130A)) {
_callbackFnPtr = &RSound6::reloadCommand24;
return 0;
}
@@ -1889,7 +1889,7 @@ int RSound6::command24() {
}
int RSound6::command25() {
- _channels[4].load(loadData(0x12FE));
+ _channels[4].playData(loadData(0x12FE));
return 0;
}
@@ -1897,7 +1897,7 @@ int RSound6::command28() {
if (isSoundActive(loadData(0x130A)))
return 0;
- if (_channels[0]._activeCount && _channels[0]._soundData == loadData(0x1A38)) {
+ if (_channels[0]._deltaCounter && _channels[0]._soundData == loadData(0x1A38)) {
_callbackFnPtr = &RSound6::reloadCommand28;
return 0;
}
@@ -1921,8 +1921,8 @@ const RSound7::CommandPtr RSound7::_commandList[38] = {
&RSound7::command36, &RSound7::command37
};
-RSound7::RSound7(Audio::Mixer *mixer) : RSound(mixer, "rsound.007",
- 0x1240, 0x1EF0, 0x67, kRSoundFadeCheckProgrammable) {
+RSound7::RSound7(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.007", 0x1240, 0x1EF0, 0x67, kRSoundFadeCheckProgrammable) {
}
int RSound7::command(int commandId, int param) {
@@ -1936,10 +1936,10 @@ int RSound7::command(int commandId, int param) {
int RSound7::command9() {
command1();
- _channels[0].load(loadData(0x1C0E));
- _channels[1].load(loadData(0x1C88));
- _channels[2].load(loadData(0x1CD4));
- _channels[3].load(loadData(0x1D4E));
+ _channels[0].playData(loadData(0x1C0E));
+ _channels[1].playData(loadData(0x1C88));
+ _channels[2].playData(loadData(0x1CD4));
+ _channels[3].playData(loadData(0x1D4E));
return 0;
}
@@ -1959,16 +1959,16 @@ int RSound7::command17() {
}
int RSound7::command18() {
- _channels[7].load(loadData(0x12FC));
+ _channels[7].playData(loadData(0x12FC));
return 0;
}
int RSound7::command19() {
if (_channels[7]._soundData == loadData(0x12FC)) {
byte *pData = loadData(0x1312);
- _channels[7]._innerLoopPtr = pData;
- _channels[7]._outerLoopPtr = pData;
- _channels[7]._activeCount = 1;
+ _channels[7]._innerLoopStart = pData;
+ _channels[7]._outerLoopStart = pData;
+ _channels[7]._deltaCounter = 1;
}
return 0;
}
@@ -1995,29 +1995,29 @@ int RSound7::command23() {
}
int RSound7::command24() {
- _channels[0].load(loadData(0x137C));
- _channels[1].load(loadData(0x1406));
- _channels[2].load(loadData(0x1492));
- _channels[3].load(loadData(0x1516));
- _channels[4].load(loadData(0x1588));
+ _channels[0].playData(loadData(0x137C));
+ _channels[1].playData(loadData(0x1406));
+ _channels[2].playData(loadData(0x1492));
+ _channels[3].playData(loadData(0x1516));
+ _channels[4].playData(loadData(0x1588));
return 0;
}
int RSound7::command25() {
command1();
- _channels[0].load(loadData(0x1612));
- _channels[1].load(loadData(0x16C8));
- _channels[2].load(loadData(0x177E));
- _channels[3].load(loadData(0x1838));
+ _channels[0].playData(loadData(0x1612));
+ _channels[1].playData(loadData(0x16C8));
+ _channels[2].playData(loadData(0x177E));
+ _channels[3].playData(loadData(0x1838));
return 0;
}
int RSound7::command27() {
- _channels[0].load(loadData(0x1932));
- _channels[1].load(loadData(0x1986));
- _channels[2].load(loadData(0x19EC));
- _channels[3].load(loadData(0x1A66));
- _channels[4].load(loadData(0x1B3C));
+ _channels[0].playData(loadData(0x1932));
+ _channels[1].playData(loadData(0x1986));
+ _channels[2].playData(loadData(0x19EC));
+ _channels[3].playData(loadData(0x1A66));
+ _channels[4].playData(loadData(0x1B3C));
return 0;
}
@@ -2073,8 +2073,8 @@ const RSound8::CommandPtr RSound8::_commandList[38] = {
&RSound8::command36, &RSound8::command37
};
-RSound8::RSound8(Audio::Mixer *mixer) : RSound(mixer, "rsound.008",
- 0x1290, 0x19A0, 0x67, kRSoundFadeCheckProgrammable) {
+RSound8::RSound8(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.008", 0x1290, 0x19A0, 0x67, kRSoundFadeCheckProgrammable) {
}
int RSound8::command(int commandId, int param) {
@@ -2092,10 +2092,10 @@ int RSound8::command9() {
}
int RSound8::command10() {
- _channels[0].load(loadData(0x115A));
- _channels[1].load(loadData(0x115A));
- _channels[2].load(loadData(0x115A));
- _channels[3].load(loadData(0x1150));
+ _channels[0].playData(loadData(0x115A));
+ _channels[1].playData(loadData(0x115A));
+ _channels[2].playData(loadData(0x115A));
+ _channels[3].playData(loadData(0x1150));
return 0;
}
@@ -2175,10 +2175,10 @@ int RSound8::command22() {
}
int RSound8::command23() {
- _channels[0].load(loadData(0x128E));
- _channels[1].load(loadData(0x128E));
- _channels[2].load(loadData(0x128E));
- _channels[3].load(loadData(0x128E));
+ _channels[0].playData(loadData(0x128E));
+ _channels[1].playData(loadData(0x128E));
+ _channels[2].playData(loadData(0x128E));
+ _channels[3].playData(loadData(0x128E));
return 0;
}
@@ -2206,9 +2206,9 @@ int RSound8::command28() {
byte *pData = loadData(0x130A);
if (!isSoundActive(pData)) {
command1();
- _channels[0].load(pData);
- _channels[1].load(loadData(0x1480));
- _channels[8].load(loadData(0x154C));
+ _channels[0].playData(pData);
+ _channels[1].playData(loadData(0x1480));
+ _channels[8].playData(loadData(0x154C));
}
return 0;
}
@@ -2217,8 +2217,8 @@ int RSound8::command29() {
byte *pData = loadData(0x15FC);
if (!isSoundActive(pData)) {
command1();
- _channels[2].load(pData);
- _channels[8].load(loadData(0x1652));
+ _channels[2].playData(pData);
+ _channels[8].playData(loadData(0x1652));
}
return 0;
}
@@ -2283,8 +2283,8 @@ const RSound9::CommandPtr RSound9::_commandList[52] = {
&RSound9::command48, &RSound9::command49, &RSound9::command50, &RSound9::command51
};
-RSound9::RSound9(Audio::Mixer *mixer) : RSound(mixer, "rsound.009",
- 0x1520, 0x8920, 0x6F, kRSoundFadeCheckAlternating) {
+RSound9::RSound9(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSound(mixer, midiDriver, "rsound.009", 0x1520, 0x8920, 0x6F, kRSoundFadeCheckAlternating) {
_callbackCounter = 0;
_callbackPeriod = 0;
_callbackFnPtr = nullptr;
@@ -2320,56 +2320,56 @@ int RSound9::command0() {
int RSound9::command9() {
_callbackCounter = 1848;
_callbackPeriod = 84;
- _channels[0].load(loadData(0x16E4));
- _channels[1].load(loadData(0x1E9E));
- _channels[2].load(loadData(0x2F9C));
- _channels[3].load(loadData(0x2644));
- _channels[4].load(loadData(0x1FF4));
- _channels[5].load(loadData(0x2382));
- _channels[6].load(loadData(0x1AAE));
+ _channels[0].playData(loadData(0x16E4));
+ _channels[1].playData(loadData(0x1E9E));
+ _channels[2].playData(loadData(0x2F9C));
+ _channels[3].playData(loadData(0x2644));
+ _channels[4].playData(loadData(0x1FF4));
+ _channels[5].playData(loadData(0x2382));
+ _channels[6].playData(loadData(0x1AAE));
return 0;
}
int RSound9::command10() {
- _channels[0].load(loadData(0x31E2));
- _channels[1].load(loadData(0x31FA));
- _channels[2].load(loadData(0x3212));
- _channels[3].load(loadData(0x322C));
+ _channels[0].playData(loadData(0x31E2));
+ _channels[1].playData(loadData(0x31FA));
+ _channels[2].playData(loadData(0x3212));
+ _channels[3].playData(loadData(0x322C));
return 0;
}
int RSound9::command11() {
- _channels[7].load(loadData(0x33E2));
+ _channels[7].playData(loadData(0x33E2));
return 0;
}
int RSound9::command12() {
- _channels[7].load(loadData(0x342E));
+ _channels[7].playData(loadData(0x342E));
return 0;
}
int RSound9::command13() {
- _channels[7].load(loadData(0x343A));
+ _channels[7].playData(loadData(0x343A));
return 0;
}
int RSound9::command14() {
- _channels[7].load(loadData(0x3442));
+ _channels[7].playData(loadData(0x3442));
return 0;
}
int RSound9::command15() {
- _channels[7].load(loadData(0x3462));
+ _channels[7].playData(loadData(0x3462));
return 0;
}
int RSound9::command16() {
- _channels[7].load(loadData(0x347A));
+ _channels[7].playData(loadData(0x347A));
return 0;
}
int RSound9::command17() {
- _channels[7].load(loadData(0x3470));
+ _channels[7].playData(loadData(0x3470));
return 0;
}
@@ -2410,15 +2410,15 @@ int RSound9::command22() {
int RSound9::command23() {
Channel *chan = playSound(0x32B0);
if (chan)
- chan->_innerLoopPtr = loadData(0x32CE);
+ chan->_innerLoopStart = loadData(0x32CE);
chan = playSound(0x32B6);
if (chan)
- chan->_innerLoopPtr = loadData(0x32CE);
+ chan->_innerLoopStart = loadData(0x32CE);
chan = playSound(0x32C8);
if (chan)
- chan->_innerLoopPtr = loadData(0x32CE);
+ chan->_innerLoopStart = loadData(0x32CE);
return 0;
}
@@ -2446,7 +2446,7 @@ int RSound9::command28() {
int v = (getRandomNumber() & 28) + 15;
byte *pData = loadData(0x334A);
pData[6] = v & 0x7F;
- _channels[7].load(pData);
+ _channels[7].playData(pData);
return 0;
}
@@ -2489,11 +2489,11 @@ int RSound9::command34() {
*loadData(0x7DCD) = 2;
*loadData(0x8791) = 2;
- _channels[0].load(loadData(0x4D2A));
- _channels[1].load(loadData(0x51AA));
- _channels[2].load(loadData(0x5634));
- _channels[3].load(loadData(0x6844));
- _channels[4].load(loadData(0x7DD0));
+ _channels[0].playData(loadData(0x4D2A));
+ _channels[1].playData(loadData(0x51AA));
+ _channels[2].playData(loadData(0x5634));
+ _channels[3].playData(loadData(0x6844));
+ _channels[4].playData(loadData(0x7DD0));
return 0;
}
@@ -2507,11 +2507,11 @@ int RSound9::command36() {
Channel *chan = playSound(0x32C2);
if (chan)
- chan->_innerLoopPtr = loadData(0x3378);
+ chan->_innerLoopStart = loadData(0x3378);
chan = playSound(0x32BC);
if (chan)
- chan->_innerLoopPtr = loadData(0x3368);
+ chan->_innerLoopStart = loadData(0x3368);
return 0;
}
@@ -2530,13 +2530,13 @@ int RSound9::command38() {
void RSound9::loadCommand38() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x1878));
- _channels[1].load(loadData(0x1F64));
- _channels[2].load(loadData(0x308E));
- _channels[3].load(loadData(0x2A10));
- _channels[4].load(loadData(0x21C8));
- _channels[5].load(loadData(0x2558));
- _channels[6].load(loadData(0x1E9A));
+ _channels[0].playData(loadData(0x1878));
+ _channels[1].playData(loadData(0x1F64));
+ _channels[2].playData(loadData(0x308E));
+ _channels[3].playData(loadData(0x2A10));
+ _channels[4].playData(loadData(0x21C8));
+ _channels[5].playData(loadData(0x2558));
+ _channels[6].playData(loadData(0x1E9A));
}
int RSound9::command39() {
@@ -2546,13 +2546,13 @@ int RSound9::command39() {
void RSound9::loadCommand39() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x1A24));
- _channels[1].load(loadData(0x1FD0));
- _channels[2].load(loadData(0x318A));
- _channels[3].load(loadData(0x2E4A));
- _channels[4].load(loadData(0x2380));
- _channels[5].load(loadData(0x2642));
- _channels[6].load(loadData(0x1E9C));
+ _channels[0].playData(loadData(0x1A24));
+ _channels[1].playData(loadData(0x1FD0));
+ _channels[2].playData(loadData(0x318A));
+ _channels[3].playData(loadData(0x2E4A));
+ _channels[4].playData(loadData(0x2380));
+ _channels[5].playData(loadData(0x2642));
+ _channels[6].playData(loadData(0x1E9C));
}
int RSound9::command40() {
@@ -2562,11 +2562,11 @@ int RSound9::command40() {
void RSound9::loadCommand40() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x4F00));
- _channels[1].load(loadData(0x534A));
- _channels[2].load(loadData(0x5CDE));
- _channels[3].load(loadData(0x6F8E));
- _channels[4].load(loadData(0x8110));
+ _channels[0].playData(loadData(0x4F00));
+ _channels[1].playData(loadData(0x534A));
+ _channels[2].playData(loadData(0x5CDE));
+ _channels[3].playData(loadData(0x6F8E));
+ _channels[4].playData(loadData(0x8110));
}
int RSound9::command41() {
@@ -2576,11 +2576,11 @@ int RSound9::command41() {
void RSound9::loadCommand41() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x4F26));
- _channels[1].load(loadData(0x53BC));
- _channels[2].load(loadData(0x5DFE));
- _channels[3].load(loadData(0x747E));
- _channels[4].load(loadData(0x8340));
+ _channels[0].playData(loadData(0x4F26));
+ _channels[1].playData(loadData(0x53BC));
+ _channels[2].playData(loadData(0x5DFE));
+ _channels[3].playData(loadData(0x747E));
+ _channels[4].playData(loadData(0x8340));
}
int RSound9::command42() {
@@ -2590,20 +2590,20 @@ int RSound9::command42() {
void RSound9::loadCommand42() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x4F30));
- _channels[1].load(loadData(0x555C));
- _channels[2].load(loadData(0x6582));
- _channels[3].load(loadData(0x7A2E));
- _channels[4].load(loadData(0x8480));
+ _channels[0].playData(loadData(0x4F30));
+ _channels[1].playData(loadData(0x555C));
+ _channels[2].playData(loadData(0x6582));
+ _channels[3].playData(loadData(0x7A2E));
+ _channels[4].playData(loadData(0x8480));
}
int RSound9::command43() {
_callbackCounter = 80;
_callbackPeriod = 80;
- _channels[0].load(loadData(0x34BE));
- _channels[1].load(loadData(0x3A46));
- _channels[2].load(loadData(0x3F52));
- _channels[3].load(loadData(0x439A));
+ _channels[0].playData(loadData(0x34BE));
+ _channels[1].playData(loadData(0x3A46));
+ _channels[2].playData(loadData(0x3F52));
+ _channels[3].playData(loadData(0x439A));
return 0;
}
@@ -2614,10 +2614,10 @@ int RSound9::command44_46() {
void RSound9::loadCommand44_46() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x3518));
- _channels[1].load(loadData(0x3AA2));
- _channels[2].load(loadData(0x403A));
- _channels[3].load(loadData(0x4486));
+ _channels[0].playData(loadData(0x3518));
+ _channels[1].playData(loadData(0x3AA2));
+ _channels[2].playData(loadData(0x403A));
+ _channels[3].playData(loadData(0x4486));
}
int RSound9::command45() {
@@ -2627,10 +2627,10 @@ int RSound9::command45() {
void RSound9::loadCommand45() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x37AC));
- _channels[1].load(loadData(0x3CF8));
- _channels[2].load(loadData(0x41E6));
- _channels[3].load(loadData(0x4630));
+ _channels[0].playData(loadData(0x37AC));
+ _channels[1].playData(loadData(0x3CF8));
+ _channels[2].playData(loadData(0x41E6));
+ _channels[3].playData(loadData(0x4630));
}
int RSound9::command47() {
@@ -2640,10 +2640,10 @@ int RSound9::command47() {
void RSound9::loadCommand47() {
_callbackFnPtr = nullptr;
- _channels[0].load(loadData(0x47D6));
- _channels[1].load(loadData(0x48FA));
- _channels[2].load(loadData(0x4A20));
- _channels[3].load(loadData(0x4BAE));
+ _channels[0].playData(loadData(0x47D6));
+ _channels[1].playData(loadData(0x48FA));
+ _channels[2].playData(loadData(0x4A20));
+ _channels[3].playData(loadData(0x4BAE));
}
int RSound9::command48() {
@@ -2655,13 +2655,13 @@ int RSound9::command48() {
}
int RSound9::command49() {
- _channels[0].load(loadData(0x12CA));
- _channels[1].load(loadData(0x132A));
- _channels[2].load(loadData(0x1384));
- _channels[3].load(loadData(0x1666));
- _channels[4].load(loadData(0x1682));
- _channels[5].load(loadData(0x16A0));
- _channels[6].load(loadData(0x16BE));
+ _channels[0].playData(loadData(0x12CA));
+ _channels[1].playData(loadData(0x132A));
+ _channels[2].playData(loadData(0x1384));
+ _channels[3].playData(loadData(0x1666));
+ _channels[4].playData(loadData(0x1682));
+ _channels[5].playData(loadData(0x16A0));
+ _channels[6].playData(loadData(0x16BE));
return 0;
}
@@ -2677,11 +2677,11 @@ void RSound9::loadCommand50() {
*loadData(0x7DCD) = 0;
*loadData(0x8791) = 0;
- _channels[0].load(loadData(0x50B8));
- _channels[1].load(loadData(0x7DCE));
- _channels[2].load(loadData(0x676A));
- _channels[3].load(loadData(0x7D08));
- _channels[4].load(loadData(0x85C4));
+ _channels[0].playData(loadData(0x50B8));
+ _channels[1].playData(loadData(0x7DCE));
+ _channels[2].playData(loadData(0x676A));
+ _channels[3].playData(loadData(0x7D08));
+ _channels[4].playData(loadData(0x85C4));
}
int RSound9::command51() {
@@ -2693,18 +2693,18 @@ int RSound9::command51() {
*loadData(0x7DCD) = 2;
*loadData(0x8791) = 2;
- _channels[0].load(loadData(0x4D3C));
- _channels[1].load(loadData(0x51EE));
- _channels[2].load(loadData(0x5A62));
- _channels[3].load(loadData(0x6986));
- _channels[4].load(loadData(0x7E5C));
+ _channels[0].playData(loadData(0x4D3C));
+ _channels[1].playData(loadData(0x51EE));
+ _channels[2].playData(loadData(0x5A62));
+ _channels[3].playData(loadData(0x6986));
+ _channels[4].playData(loadData(0x7E5C));
return 0;
}
/*-----------------------------------------------------------------------*/
-RSoundDemo9::RSoundDemo9(Audio::Mixer *mixer) :
- RSoundDemo(mixer, "rsound.009", 0x11D0, 0x3664, 0x69, 5) {
+RSoundDemo9::RSoundDemo9(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver) :
+ RSoundDemo(mixer, midiDriver, "rsound.009", 0x11D0, 0x3664, 0x69, 5) {
}
int RSoundDemo9::executeDemoCommonCommand(int commandId) {
@@ -2798,7 +2798,7 @@ int RSoundDemo9::command(int commandId, int param) {
for (uint index = 0; index < 3; ++index) {
const int channel = startEffectVoice(sequences[index]);
if (channel >= 0)
- voice(channel)._innerLoopPtr = loadData(0x1340);
+ voice(channel)._innerLoopStart = loadData(0x1340);
}
break;
}
@@ -2856,11 +2856,11 @@ int RSoundDemo9::command(int commandId, int param) {
int channel = startEffectVoice(0x1334);
if (channel >= 0)
- voice(channel)._innerLoopPtr = loadData(0x13EA);
+ voice(channel)._innerLoopStart = loadData(0x13EA);
channel = startEffectVoice(0x132E);
if (channel >= 0)
- voice(channel)._innerLoopPtr = loadData(0x13DA);
+ voice(channel)._innerLoopStart = loadData(0x13DA);
break;
}
case 37: {
diff --git a/engines/mads/nebular/sound/rsound_nebular.h b/engines/mads/nebular/sound/rsound_nebular.h
index a7e71d0abf6..e0cd91de427 100644
--- a/engines/mads/nebular/sound/rsound_nebular.h
+++ b/engines/mads/nebular/sound/rsound_nebular.h
@@ -34,7 +34,7 @@ private:
int _firstEffectChannel;
protected:
- RSoundDemo(Audio::Mixer *mixer, const Common::Path &filename,
+ RSoundDemo(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver, const Common::Path &filename,
int dataOffset, int dataSize, int sysExOffset,
int firstEffectChannel);
@@ -104,7 +104,7 @@ private:
int command40();
int command41();
public:
- RSound1(Audio::Mixer *mixer);
+ RSound1(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -119,7 +119,7 @@ private:
int executeDemoCommonCommand(int commandId);
public:
- explicit RSoundDemo1(Audio::Mixer *mixer);
+ explicit RSoundDemo1(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -186,7 +186,7 @@ private:
int command42();
int command43();
public:
- RSound2(Audio::Mixer *mixer);
+ RSound2(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -296,7 +296,7 @@ private:
int command59();
int command60();
public:
- RSound3(Audio::Mixer *mixer);
+ RSound3(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -366,7 +366,7 @@ private:
int command58();
int command59();
public:
- RSound4(Audio::Mixer *mixer);
+ RSound4(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -414,7 +414,7 @@ private:
int command40();
int command41();
public:
- RSound5(Audio::Mixer *mixer);
+ RSound5(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -467,7 +467,7 @@ private:
int command25();
int command28();
public:
- RSound6(Audio::Mixer *mixer);
+ RSound6(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -498,7 +498,7 @@ private:
int command36();
int command37();
public:
- RSound7(Audio::Mixer *mixer);
+ RSound7(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -544,7 +544,7 @@ private:
int command36();
int command37();
public:
- RSound8(Audio::Mixer *mixer);
+ RSound8(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -624,7 +624,7 @@ private:
void loadCommand47();
void loadCommand50();
public:
- RSound9(Audio::Mixer *mixer);
+ RSound9(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
@@ -635,7 +635,7 @@ private:
int executeDemoCommonCommand(int commandId);
public:
- explicit RSoundDemo9(Audio::Mixer *mixer);
+ explicit RSoundDemo9(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver);
int command(int commandId, int param) override;
};
diff --git a/engines/mads/nebular/sound/sound.cpp b/engines/mads/nebular/sound/sound.cpp
index e42073cd865..5b4375c1acf 100644
--- a/engines/mads/nebular/sound/sound.cpp
+++ b/engines/mads/nebular/sound/sound.cpp
@@ -70,7 +70,7 @@ void RexSoundManager::validate() {
}
void RexSoundManager::loadDriver(int sectionNumber) {
- removeDriver();
+ closeDriver();
if (_isDemo && _driverType == SOUND_ADLIB) {
switch (sectionNumber) {
@@ -93,39 +93,39 @@ void RexSoundManager::loadDriver(int sectionNumber) {
// The demo shares RSOUND.001 across numbered gameplay sections
// and uses RSOUND.009 only for its opening presentation.
if (sectionNumber == 9)
- _driver = new RSoundDemo9(_mixer);
+ _driver = new RSoundDemo9(_mixer, _midiDriver);
else
- _driver = new RSoundDemo1(_mixer);
+ _driver = new RSoundDemo1(_mixer, _midiDriver);
break;
}
switch (sectionNumber) {
case 1:
- _driver = new RSound1(_mixer);
+ _driver = new RSound1(_mixer, _midiDriver);
break;
case 2:
- _driver = new RSound2(_mixer);
+ _driver = new RSound2(_mixer, _midiDriver);
break;
case 3:
- _driver = new RSound3(_mixer);
+ _driver = new RSound3(_mixer, _midiDriver);
break;
case 4:
- _driver = new RSound4(_mixer);
+ _driver = new RSound4(_mixer, _midiDriver);
break;
case 5:
- _driver = new RSound5(_mixer);
+ _driver = new RSound5(_mixer, _midiDriver);
break;
case 6:
- _driver = new RSound6(_mixer);
+ _driver = new RSound6(_mixer, _midiDriver);
break;
case 7:
- _driver = new RSound7(_mixer);
+ _driver = new RSound7(_mixer, _midiDriver);
break;
case 8:
- _driver = new RSound8(_mixer);
+ _driver = new RSound8(_mixer, _midiDriver);
break;
case 9:
- _driver = new RSound9(_mixer);
+ _driver = new RSound9(_mixer, _midiDriver);
break;
default:
return;
Commit: e815605b1bab62779765f6de4006bd2b3291fb93
https://github.com/scummvm/scummvm/commit/e815605b1bab62779765f6de4006bd2b3291fb93
Author: Coen Rampen (crampen at gmail.com)
Date: 2026-08-16T17:11:24+02:00
Commit Message:
MADS: Fixes for Rex MT-32 sound driver
Changed paths:
engines/mads/core/sound_manager.cpp
engines/mads/core/sound_manager.h
engines/mads/nebular/sound/rsound.cpp
engines/mads/nebular/sound/rsound.h
engines/mads/nebular/sound/rsound_nebular.cpp
engines/mads/nebular/sound/rsound_nebular.h
engines/mads/nebular/sound/sound.cpp
diff --git a/engines/mads/core/sound_manager.cpp b/engines/mads/core/sound_manager.cpp
index 0155a3d52a6..1517a4f2281 100644
--- a/engines/mads/core/sound_manager.cpp
+++ b/engines/mads/core/sound_manager.cpp
@@ -33,9 +33,9 @@ class Mixer;
namespace MADS {
- const uint32 SoundManager::UPDATE_DELTA = 1000000 / 60;
+const uint32 SoundManager::UPDATE_DELTA = 1000000 / 60;
- SoundManager::SoundManager(Audio::Mixer *mixer, bool &soundFlag,
+SoundManager::SoundManager(Audio::Mixer *mixer, bool &soundFlag,
bool supportsGeneralMidi) : _mixer(mixer), _soundFlag(soundFlag) {
_updateDeltaRemainder = 0;
_driverCallbackDelta = 0;
@@ -48,15 +48,6 @@ namespace MADS {
switch (musicType) {
case MT_MT32:
_driverType = SOUND_MT32;
- _midiDriver = new MidiDriver_MT32GM(MusicType::MT_MT32);
- int returnCode;
- returnCode = _midiDriver->open();
- if (returnCode != 0)
- error("RSound - Failed to open MIDI music driver - error code %d.", returnCode);
-
- _driverCallbackDelta = _midiDriver->getBaseTempo();
- _midiDriver->setTimerCallback(this, &timerCallback);
-
break;
case MT_GM:
case MT_GS:
@@ -175,12 +166,21 @@ void SoundManager::onTimer() {
// The frequency of the callbacks is dependent on the underlying driver
// implementation and might not be 60Hz. Adjust to make sure poll() is called
// with the correct frequency.
+ /*
_updateDeltaRemainder += _driverCallbackDelta;
while (_updateDeltaRemainder >= UPDATE_DELTA) {
if (_driver)
_driver->poll();
_updateDeltaRemainder -= UPDATE_DELTA;
}
+ */
+
+ uint32 serviceTicks = _hostTimer.advance(_driverCallbackDelta, 1000000);
+ while (serviceTicks--) {
+ // RSOUND export 4 is a return stub in every audited overlay.
+ if (_driver && _hostTimer.pollDue())
+ _driver->poll();
+ }
}
void SoundManager::timerCallback(void *data) {
diff --git a/engines/mads/core/sound_manager.h b/engines/mads/core/sound_manager.h
index 22d47028219..f03c36546bb 100644
--- a/engines/mads/core/sound_manager.h
+++ b/engines/mads/core/sound_manager.h
@@ -27,6 +27,7 @@
#include "common/memstream.h"
#include "common/mutex.h"
#include "common/queue.h"
+#include "native_sound_timer.h"
namespace Audio {
class Mixer;
@@ -115,6 +116,8 @@ protected:
Common::Queue<QueuedCommand> _queuedCommands;
int _masterVolume = 255;
+ NativeSoundTimer _hostTimer;
+
protected:
/**
* Load the particular section sound handler
diff --git a/engines/mads/nebular/sound/rsound.cpp b/engines/mads/nebular/sound/rsound.cpp
index 1df08cb7bc2..97bb3726bac 100644
--- a/engines/mads/nebular/sound/rsound.cpp
+++ b/engines/mads/nebular/sound/rsound.cpp
@@ -59,9 +59,14 @@ void Channel::setFadeOut(bool fadeOut) {
}
void Channel::playData(byte *soundData) {
+ bool ticksProcessingDisabled = _owner->_ticksProcessingDisabled;
+ _owner->_ticksProcessingDisabled = true;
+
loadData(soundData);
_deltaCounter = 1;
_owner->sendPitchBend(_midiChannel, 0x40);
+
+ _owner->_ticksProcessingDisabled = ticksProcessingDisabled;
}
/*-----------------------------------------------------------------------*/
@@ -70,12 +75,13 @@ RSound::RSound(Audio::Mixer *mixer, MidiDriver_MT32GM *midiDriver, const Common:
int dataOffset, int dataSize, int sysExOffset, RSoundFadeCheckMode fadeCheckMode) :
SoundDriver(mixer, filename, dataOffset, dataSize) {
_commandParam = 0;
- _frameCounter = 0;
- _isDisabled = false;
+ _ticksSinceLastCommand = 0;
+ _ticksProcessingDisabled = false;
+ _mute = false;
_masterVolume = 255;
+ // FIXME RSOUND.008 initializes this to 0x005C; is the initial value different per driver?
_randomSeed = 1234;
- _lastMidiStatus = 0;
- _noteTriggeredThisPoll = false;
+ _runningStatus = 0;
_pollResult = 0;
_resultFlag = 0;
_sysExOffset = sysExOffset;
@@ -152,7 +158,7 @@ int RSound::stop() {
int RSound::poll() {
Common::StackLock slock(_driverMutex);
- update();
+ processTick();
int result = _pollResult;
_pollResult = 0;
@@ -166,25 +172,26 @@ void RSound::resultCheck() {
}
}
-Channel *RSound::playSound(int offset) {
- return playSoundData(loadData(offset));
+Channel *RSound::playSoundCh5To8(int offset) {
+ return allocateAndPlay(loadData(offset));
+}
+
+Channel *RSound::playSoundCh1To8(int offset) {
+ return allocateAndPlay(loadData(offset), 0);
}
-Channel *RSound::playSoundData(byte *pData, int startingChannel) {
- // playSound() (startingChannel=5) deliberately excludes channel 9
- // (index 8), matching rsound.009's disassembly. playSoundAny()
- // (startingChannel=0) reaches all 9 channels.
- int endChannel = (startingChannel == 0) ? RSOUND_CHANNEL_COUNT : RSOUND_CHANNEL_COUNT - 1;
+Channel *RSound::allocateAndPlay(byte *pData, int startingChannel) {
+ int endChannel = RSOUND_CHANNEL_COUNT - 1;
// Scan for a free channel
for (int i = startingChannel; i < endChannel; ++i) {
- if (!_channels[i]._deltaCounter) {
+ if (_channels[i]._deltaCounter == 0) {
_channels[i].playData(pData);
return &_channels[i];
}
}
- // None found; fall back to an interruptable (pending-stop) channel
+ // None found; fall back to a channel that is fading out to stop
for (int i = endChannel - 1; i >= startingChannel; --i) {
if (_channels[i]._fadeOutActive) {
_channels[i].playData(pData);
@@ -192,21 +199,22 @@ Channel *RSound::playSoundData(byte *pData, int startingChannel) {
}
}
+ // No available channel
return nullptr;
}
-bool RSound::isSoundActive(byte *pData) {
+bool RSound::isSoundPlaying(byte *pData) {
// Deliberately excludes channel 9 (index 8), matching the disassembly -
- // same as playSoundData()'s scan never reaching channel 9 either.
+ // same as allocateAndPlay()'s scan never reaching channel 9 either.
for (int i = 0; i < RSOUND_CHANNEL_COUNT - 1; ++i) {
- if (_channels[i]._deltaCounter && _channels[i]._soundData == pData)
+ if (_channels[i]._deltaCounter > 0 && _channels[i]._soundData == pData)
return true;
}
return false;
}
-int RSound::getRandomNumber() {
+int RSound::generateRandomNumber() {
int v = 0x9249 + (int)_randomSeed;
_randomSeed = ((v >> 3) | (v << 13)) & 0xFFFF;
return _randomSeed;
@@ -215,7 +223,7 @@ int RSound::getRandomNumber() {
void RSound::setVolume(int volume) {
_masterVolume = CLIP(volume, 0, 255);
for (int i = 0; i < RSOUND_CHANNEL_COUNT; ++i)
- sendVolume(i + 1, _isDisabled ? 0 : _channels[i]._volume);
+ sendVolume(i + 1, _mute ? 0 : _channels[i]._volume);
}
/*-----------------------------------------------------------------------*/
@@ -239,7 +247,7 @@ void RSound::sendPitchBend(int midiChannel, int value) {
_midiDriver->send(MidiDriver::MIDI_COMMAND_PITCH_BEND | midiChannel, 0, value);
}
-void RSound::sendPan(int midiChannel, int value) {
+void RSound::sendPanning(int midiChannel, int value) {
_midiDriver->send(MidiDriver::MIDI_COMMAND_CONTROL_CHANGE | midiChannel, MidiDriver::MIDI_CONTROLLER_PANNING, value);
}
@@ -247,7 +255,7 @@ void RSound::muteChannel(int midiChannel) {
sendVolume(midiChannel, 0);
}
-void RSound::restoreChannelVolume(int midiChannel, int volume) {
+void RSound::unmuteChannel(int midiChannel, int volume) {
sendVolume(midiChannel, volume);
}
@@ -309,19 +317,19 @@ void RSound::sendSysExSequence() {
/*-----------------------------------------------------------------------*/
-void RSound::Channel_flushHeldNotes(Channel *channel) {
- byte *slots = _heldNotes[channel->_midiChannel];
+void RSound::Channel_turnOffActiveNotes(Channel *channel) {
+ byte *channelActiveNotes = _activeNotes[channel->_midiChannel];
for (int i = 0; i < 4; ++i) {
- if (slots[i] == 0xFF)
+ if (channelActiveNotes[i] == 0xFF)
break;
- sendNoteOn(channel->_midiChannel, slots[i], 0); // velocity 0 = note off
- slots[i] = 0xFF;
+ sendNoteOn(channel->_midiChannel, channelActiveNotes[i], 0); // velocity 0 = note off
+ channelActiveNotes[i] = 0xFF;
}
}
-void RSound::Channel_checkFade(Channel *channel) {
+void RSound::Channel_processFadeOut(Channel *channel) {
if (!channel->_deltaCounter)
return;
if (!channel->_fadeOutActive)
@@ -343,7 +351,7 @@ void RSound::Channel_checkFade(Channel *channel) {
}
}
-void RSound::checkFadingChannels() {
+void RSound::processChannelFadeOuts() {
if (_fadeCheckMode == kRSoundFadeCheckAlternating) {
_fadeCheckAlternate = !_fadeCheckAlternate;
if (_fadeCheckAlternate)
@@ -358,30 +366,25 @@ void RSound::checkFadingChannels() {
}
for (int i = 0; i < RSOUND_CHANNEL_COUNT; ++i)
- Channel_checkFade(&_channels[i]);
+ Channel_processFadeOut(&_channels[i]);
}
-void RSound::Channel_pollActive(Channel *channel) {
- if (!channel->_deltaCounter)
+void RSound::Channel_processTick(Channel *channel) {
+ if (channel->_deltaCounter == 0)
return;
int midiChannel = channel->_midiChannel;
if (channel->_noteDurationCounter > 0 && --channel->_noteDurationCounter == 0)
- Channel_flushHeldNotes(channel);
+ Channel_turnOffActiveNotes(channel);
if (--channel->_deltaCounter <= 0) {
- for (;;) {
+ bool chordEventProcessed = false;
+ while (!chordEventProcessed) {
byte *pSrc = channel->_pSrc;
if (*pSrc < 0x80) {
// Plain (note, duration) pair
- if (_noteTriggeredThisPoll) {
- // Already fired a note-on this poll tick - defer to next tick
- _noteTriggeredThisPoll = false;
- break;
- }
-
byte note = pSrc[0];
byte duration = pSrc[1];
channel->_note = note;
@@ -389,19 +392,19 @@ void RSound::Channel_pollActive(Channel *channel) {
channel->_pSrc = pSrc + 2;
if (!note || !duration) {
- Channel_flushHeldNotes(channel);
+ Channel_turnOffActiveNotes(channel);
} else {
channel->_noteDurationCounter = channel->_deltaCounter - channel->_noteDurationOffset;
bool skipRetrigger = false;
- if ((int8)channel->_noteDurationOffset < 0 && _heldNotes[midiChannel][0] == note)
+ if ((int8)channel->_noteDurationOffset < 0 && _activeNotes[midiChannel][0] == note)
skipRetrigger = true;
if (!skipRetrigger) {
- Channel_flushHeldNotes(channel);
+ Channel_turnOffActiveNotes(channel);
sendNoteOn(midiChannel, note, channel->_velocity);
}
- _heldNotes[midiChannel][0] = note;
+ _activeNotes[midiChannel][0] = note;
}
break;
@@ -417,7 +420,7 @@ void RSound::Channel_pollActive(Channel *channel) {
case 1: { // 0xF2: self-modifying randomize (byte swap in the data stream)
int v1 = *++pSrc;
++pSrc;
- int v2 = (v1 - 1) & getRandomNumber();
+ int v2 = (v1 - 1) & generateRandomNumber();
int v3 = pSrc[v2];
int v4 = pSrc[v1];
pSrc[v4 + v1 + 1] = v3;
@@ -434,14 +437,14 @@ void RSound::Channel_pollActive(Channel *channel) {
case 3: // 0xF4: set pan directly and send
channel->_panning = pSrc[1];
- sendPan(midiChannel, channel->_panning);
+ sendPanning(midiChannel, channel->_panning);
channel->_pSrc = pSrc + 2;
break;
case 4: { // 0xF5: chord note-on trigger (up to 4 simultaneous notes)
byte noteCount = pSrc[1];
byte *notes = pSrc + 2;
- byte *slots = _heldNotes[midiChannel];
+ byte *slots = _activeNotes[midiChannel];
int i;
for (i = 0; i < noteCount; ++i) {
@@ -464,7 +467,7 @@ void RSound::Channel_pollActive(Channel *channel) {
}
channel->_pSrc = pSrc + noteCount + 3;
- _noteTriggeredThisPoll = true;
+ chordEventProcessed = true;
break;
}
@@ -498,7 +501,7 @@ void RSound::Channel_pollActive(Channel *channel) {
case 9: // 0xFA: setup pitch-bend ramp
channel->_pitchSlideSpeed = pSrc[1];
- channel->_pitchSlideStepSize = pSrc[2];
+ channel->_pitchSlideStepSize = (int8) pSrc[2];
channel->_pitchSlideDurationCounter = pSrc[3];
channel->_pitchSlideCounter = 1;
channel->_pSrc = pSrc + 4;
@@ -572,13 +575,22 @@ void RSound::Channel_pollActive(Channel *channel) {
}
// Fade tail: pitch bend, volume, pan
- if (channel->_pitchSlideStepSize) {
- if (!--channel->_pitchSlideCounter) {
+ if (channel->_pitchSlideStepSize != 0) {
+ if (--channel->_pitchSlideCounter == 0) {
channel->_pitchSlideCounter = channel->_pitchSlideSpeed;
- channel->_pitchBend += channel->_pitchSlideStepSize;
+ int newPitchBend = channel->_pitchBend + channel->_pitchSlideStepSize;
+ if (newPitchBend < 0 || newPitchBend > 0x7F) {
+ // Overflow will cause the driver to output invalid MIDI events.
+ // This actually happens in the original code, in the intro,
+ // when Rex lands his ship.
+ warning("Pitch bend overflow; terminating pitch slide");
+ channel->_pitchSlideStepSize = 0;
+ newPitchBend = CLIP(newPitchBend, 0, 0x7F);
+ }
+ channel->_pitchBend = newPitchBend;
sendPitchBend(midiChannel, channel->_pitchBend);
}
- if (!--channel->_pitchSlideDurationCounter)
+ if (--channel->_pitchSlideDurationCounter == 0)
channel->_pitchSlideStepSize = 0;
}
@@ -607,72 +619,78 @@ void RSound::Channel_pollActive(Channel *channel) {
channel->_panningSweepCounter = 0;
}
channel->_panning = newPan;
- sendPan(midiChannel, newPan);
+ sendPanning(midiChannel, newPan);
}
}
}
-void RSound::pollAllChannels() {
+void RSound::processTickAllChannels() {
for (int i = 0; i < RSOUND_CHANNEL_COUNT; ++i)
- Channel_pollActive(&_channels[i]);
+ Channel_processTick(&_channels[i]);
}
-void RSound::update() {
- getRandomNumber();
- if (_isDisabled)
+void RSound::processTick() {
+ generateRandomNumber();
+ if (_ticksProcessingDisabled)
return;
tickCallback();
- ++_frameCounter;
- pollAllChannels();
- checkFadingChannels();
+ ++_ticksSinceLastCommand;
+ processTickAllChannels();
+ processChannelFadeOuts();
}
/*-----------------------------------------------------------------------*/
/**
* Zeroes _deltaCounter and the three fade-step fields for channels in
- * [first, last).
+ * [first, last].
* Deliberately does NOT touch the loop pointers, volume, program, pan etc,
* matching the original.
*/
-void RSound::resetChannelRange(int first, int last) {
- bool wasDisabled = _isDisabled;
- _isDisabled = true;
+void RSound::resetChannelRange(int firstChannel, int lastChannel, bool includeChannel9) {
+ _ticksProcessingDisabled = true;
- for (int i = first; i < last; ++i) {
+ for (int i = firstChannel - 1; i < lastChannel; ++i) {
_channels[i]._deltaCounter = 0;
_channels[i]._pitchSlideStepSize = 0;
_channels[i]._volumeFadeStepSize = 0;
_channels[i]._panningSweepStepSize = 0;
}
- _isDisabled = wasDisabled;
+ if (lastChannel <= 8 && includeChannel9) {
+ _channels[8]._deltaCounter = 0;
+ _channels[8]._pitchSlideStepSize = 0;
+ _channels[8]._volumeFadeStepSize = 0;
+ _channels[8]._panningSweepStepSize = 0;
+ }
+
+ _ticksProcessingDisabled = false;
}
-void RSound::resetHeldNotes() {
+void RSound::clearActiveNotes() {
for (int i = 0; i < RSOUND_CHANNEL_COUNT + 1; ++i)
for (int j = 0; j < 4; ++j)
- _heldNotes[i][j] = 0xFF;
+ _activeNotes[i][j] = 0xFF;
}
-void RSound::resetHeldNotesRange(int firstChannel, int lastChannel) {
+void RSound::clearActiveNotesRange(int firstChannel, int lastChannel) {
assert(firstChannel >= 1 && lastChannel <= RSOUND_CHANNEL_COUNT &&
firstChannel <= lastChannel);
for (int channel = firstChannel; channel <= lastChannel; ++channel)
for (int slot = 0; slot < 4; ++slot)
- _heldNotes[channel][slot] = 0xFF;
+ _activeNotes[channel][slot] = 0xFF;
}
/**
- * Resets all 9 channels and the held-notes table.
+ * Resets all 9 channels and the active notes table.
* Called both from the constructor (mirroring rsound_init) and from
* command0.
*/
void RSound::resetAllChannels() {
- resetChannelRange(0, RSOUND_CHANNEL_COUNT);
- resetHeldNotes();
+ resetChannelRange(1, RSOUND_CHANNEL_COUNT);
+ clearActiveNotes();
}
/**
@@ -690,9 +708,6 @@ void RSound::sendMidiChannelReset(int first, int last) {
}
int RSound::command0() {
- bool isDisabled = _isDisabled;
- _isDisabled = true;
-
resetAllChannels();
setFadeCheckPeriod(0);
sendMidiChannelReset(1, RSOUND_CHANNEL_COUNT);
@@ -704,7 +719,6 @@ int RSound::command0() {
// copy of this table, so no per-driver command0() override is needed.
sendSysEx(_sysExOffset);
- _isDisabled = isDisabled;
return 0;
}
@@ -716,39 +730,49 @@ int RSound::command1() {
}
int RSound::command2() {
- // Channels 1-5 (also reinitializes the held-notes
+ // Channels 1-4 and 9 (also reinitializes the held-notes
// table) plus the MIDI channel reset for those same channels.
- resetChannelRange(0, 5);
- resetHeldNotes();
+ resetChannelRange(1, 4, true);
+ clearActiveNotes();
setFadeCheckPeriod(0);
- sendMidiChannelReset(1, 5);
+ // The original code does not reset MIDI channel 9, which is
+ // probably an oversight.
+ sendMidiChannelReset(1, 4);
+ sendMidiChannelReset(9, 9);
return 0;
}
int RSound::command3() {
+ // Start fade-out to stop for channels 1-4 and 9.
setFadeCheckPeriod(1);
- for (int i = 0; i < 5; ++i)
+ for (int i = 0; i < 4; ++i)
_channels[i].setFadeOut(true);
+ _channels[8].setFadeOut(true);
return 0;
}
int RSound::command4() {
- // Channels 6-9 (does NOT touch the held-notes
+ // Channels 5-8 (does NOT touch the held-notes
// table) plus the MIDI channel reset for those same channels.
- resetChannelRange(5, RSOUND_CHANNEL_COUNT);
+ resetChannelRange(5, 8);
setFadeCheckPeriod(0);
- sendMidiChannelReset(6, RSOUND_CHANNEL_COUNT);
+ // The original code also resets MIDI channel 9, which is
+ // probably incorrect.
+ sendMidiChannelReset(5, 8);
return 0;
}
int RSound::command5() {
+ // Start fade-out to stop for channels 5-8.
setFadeCheckPeriod(1);
- for (int i = 5; i < RSOUND_CHANNEL_COUNT; ++i)
+ for (int i = 4; i < 8; ++i)
_channels[i].setFadeOut(true);
return 0;
}
int RSound::command6() {
+ _ticksProcessingDisabled = true;
+ _mute = true;
for (int ch = 1; ch <= RSOUND_CHANNEL_COUNT; ++ch)
muteChannel(ch);
return 0;
@@ -756,7 +780,9 @@ int RSound::command6() {
int RSound::command7() {
for (int i = 0; i < RSOUND_CHANNEL_COUNT; ++i)
- restoreChannelVolume(_channels[i]._midiChannel, _channels[i]._volume);
+ unmuteChannel(_channels[i]._midiChannel, _channels[i]._volume);
+ _mute = false;
+ _ticksProcessingDisabled = false;
return 0;
}
diff --git a/engines/mads/nebular/sound/rsound.h b/engines/mads/nebular/sound/rsound.h
index fb3c0e3fe59..b427785e8cc 100644
--- a/engines/mads/nebular/sound/rsound.h
+++ b/engines/mads/nebular/sound/rsound.h
@@ -43,9 +43,10 @@ enum RSoundFadeCheckMode {
/**
* Represents the data for a channel on the Roland MT-32 / MPU-401 driver.
* Ported from the Channel struct identified in rsound.009's disassembly;
- * field names/roles were derived by tracing Channel_pollActive() (the
+ * field names/roles were derived by tracing Channel_processTick() (the
* per-channel opcode interpreter) and cross-referencing against the
* equivalent AdlibChannel fields in asound.h.
+ * Note: fields have been renamed here; this will be done in asound.* too.
*
* Confirmed against the real DOS struct layout (IDA struct dump,
* sizeof=0x22): every field below from _deltaCounter through _soundData
@@ -139,9 +140,9 @@ class RSound : public SoundDriver {
private:
uint16 _randomSeed;
int _masterVolume;
- byte _lastMidiStatus; // running-status cache, avoids resending an unchanged status byte
- bool _noteTriggeredThisPoll; // throttles note-on dispatch to at most one per update() tick, across all channels
- byte _heldNotes[RSOUND_CHANNEL_COUNT + 1][4]; // per-MIDI-channel held-note slots (index 0 unused; channels are 1-9)
+ byte _runningStatus; // running-status cache, avoids resending an unchanged status byte
+ // Note that the ScummVM MIDI drivers do not use this; they always send the status byte
+ byte _activeNotes[RSOUND_CHANNEL_COUNT + 1][4]; // The note(s) currently playing on each MIDI channel (index 0 unused; channels are 1-9)
RSoundFadeCheckMode _fadeCheckMode;
bool _fadeCheckAlternate;
int _fadeCheckCounter;
@@ -151,8 +152,7 @@ private:
* Data-segment offset of this driver's own "command0_array" (the
* MT-32 title-display + patch-init SysEx table sent by command0()).
* Each driver has its own copy of this table at its own offset
- * within its own resource file - unlike the fixed 5-byte SysEx
- * header (_sysExHeader below), the table's content differs per
+ * within its own resource file. The table's contents differs per
* driver beyond a shared prefix, so it can't be hardcoded once;
* parameterizing the offset via the constructor avoids needing a
* command0() override in every derived class.
@@ -161,11 +161,10 @@ private:
MidiDriver_MT32GM *_midiDriver;
uint32 _driverCallbackDelta;
- NativeSoundTimer _hostTimer;
- void update();
- void pollAllChannels();
- void Channel_pollActive(Channel *channel);
+ void processTick();
+ void processTickAllChannels();
+ void Channel_processTick(Channel *channel);
/**
* Resets all 9 channels and the held-notes table.
@@ -173,19 +172,20 @@ private:
void resetAllChannels();
/**
- * Run pending-stop volume decay using the scheduler embedded in the
- * loaded overlay. Sections 1, 2, and 9 and both demo overlays use a
- * fixed every-other-poll toggle. Sections 3-8 use a programmable
+ * Process channels fading out to stop. Not to be confused with the
+ * volume fade event 0xF8.
+ * Sections 1, 2, and 9 and both demo overlays use a fixed
+ * every-other-poll toggle. Sections 3-8 use a programmable
* countdown; zero disables it and the counter reloads after each pass.
*/
- void checkFadingChannels();
- void Channel_checkFade(Channel *channel);
+ void processChannelFadeOuts();
+ void Channel_processFadeOut(Channel *channel);
/**
- * Sends Note-Off (velocity 0) for all currently-held notes on the
- * given channel's MIDI channel, then clears the held-note table for it.
+ * Sends Note-Off (velocity 0) for all active notes on the
+ * given channel's MIDI channel, then clears the active note table for it.
*/
- void Channel_flushHeldNotes(Channel *channel);
+ void Channel_turnOffActiveNotes(Channel *channel);
protected:
int _commandParam;
@@ -195,21 +195,24 @@ protected:
_fadeCheckPeriod = period;
}
- /** Clear the active and fade state for channel indices in [first, last). */
- void resetChannelRange(int first, int last);
+ /**
+ * Clear the active and fade state for MIDI channels in [first, last].
+ * Specify includeChannel9 to also reset MIDI channel 9.
+ */
+ void resetChannelRange(int firstChannel, int lastChannel, bool includeChannel9 = false);
- /** Reset the per-MIDI-channel held-note tracking table to empty. */
- void resetHeldNotes();
+ /** Reset the per-MIDI-channel active note tracking table to empty. */
+ void clearActiveNotes();
- /** Reset held-note slots for the inclusive MIDI-channel range. */
- void resetHeldNotesRange(int firstChannel, int lastChannel);
+ /** Reset active note slots for the inclusive MIDI-channel range. */
+ void clearActiveNotesRange(int firstChannel, int lastChannel);
byte *loadData(int offset) {
return &_soundData[offset];
}
/**
- * Hook called once per update() frame, immediately after the disabled
+ * Hook called once per processTick() frame, immediately after the disabled
* check and before channel polling. Only RSound9's driver data makes
* use of a recurring deferred-callback timer (g_callbackCounter/
* g_callbackPeriod/_soundPtr in the original disassembly, mirroring
@@ -222,42 +225,43 @@ protected:
void resultCheck();
/**
- * Play the specified sound, using any free channel from 6 to 8.
- * Channel 9 is deliberately never touched here - matches the
- * disassembly, which never includes it in this scan. Returns the
- * channel that was used (or nullptr if none was free), since some
- * commands poke the just-loaded channel's loop pointer directly
- * afterward.
+ * Play the specified sound using any free channel from 5 to 8.
+ * Returns the channel that was used (or nullptr if none was free),
+ * since some commands poke the just-loaded channel's loop pointer
+ * directly afterward.
*/
- Channel *playSound(int offset);
+ Channel *playSoundCh5To8(int offset);
/**
- * Play the specified sound using any channel from 0 to 8, including
- * channel 9 - confirmed distinct from playSound() by rsound.001's
- * disassembly (rsound_command30/32/38).
+ * Play the specified sound using any free channel from 1 to 8.
*/
- Channel *playSoundAny(int offset) {
- return playSoundData(loadData(offset), 0);
- }
+ Channel *playSoundCh1To8(int offset);
- Channel *playSoundData(byte *pData, int startingChannel = 5);
+ /**
+ * Allocates a MIDI channel, loads the specified sound data into it
+ * and starts playback. Allocation will look for a free channel in
+ * the range starting with the specified channel (default 5) and
+ * ending with channel 8. If no suitable channel could be found,
+ * nullptr is returned and the sound data is not played.
+ */
+ Channel *allocateAndPlay(byte *pData, int startingChannel = 5);
/**
* Checks to see whether the given block of data is already loaded into a channel.
*/
- bool isSoundActive(byte *pData);
+ bool isSoundPlaying(byte *pData);
- int getRandomNumber();
+ int generateRandomNumber();
// ---- Low-level MIDI send helpers -------------------------------
- // All send through the ScummVM MT-32/MIDI driver.
+ // All send through the ScummVM MT-32 / General MIDI driver.
void sendNoteOn(int midiChannel, int note, int velocity);
void sendProgramChange(int midiChannel, int program);
void sendVolume(int midiChannel, int volume);
void sendPitchBend(int midiChannel, int value);
- void sendPan(int midiChannel, int value);
+ void sendPanning(int midiChannel, int value);
void muteChannel(int midiChannel);
- void restoreChannelVolume(int midiChannel, int volume);
+ void unmuteChannel(int midiChannel, int volume);
/**
* Resets the MIDI channel state (all notes off, reset all
@@ -305,8 +309,9 @@ protected:
public:
Channel _channels[RSOUND_CHANNEL_COUNT];
- int _frameCounter;
- bool _isDisabled;
+ int _ticksSinceLastCommand;
+ bool _ticksProcessingDisabled;
+ bool _mute;
int _pollResult;
int _resultFlag;
@@ -317,6 +322,7 @@ public:
/**
* Constructor
* @param mixer Mixer
+ * @param midiDriver MIDI driver instance used for MIDI message output
* @param filename Specifies the Roland sound player file to use
* @param dataOffset Offset in the file of the data segment
* @param dataSize Size of the data segment
@@ -335,8 +341,8 @@ public:
}
void setVolume(int volume) override;
- int getFrameCounter() {
- return _frameCounter;
+ int getTicksSinceLastCommand() {
+ return _ticksSinceLastCommand;
}
};
diff --git a/engines/mads/nebular/sound/rsound_nebular.cpp b/engines/mads/nebular/sound/rsound_nebular.cpp
index cb31b8234f3..ce7152af906 100644
--- a/engines/mads/nebular/sound/rsound_nebular.cpp
+++ b/engines/mads/nebular/sound/rsound_nebular.cpp
@@ -83,8 +83,8 @@ void RSoundDemo::requestStopAll() {
void RSoundDemo::stopAndResetRange(int firstChannel, int channelCount) {
assert(firstChannel >= 0 && channelCount > 0 &&
firstChannel + channelCount <= RSOUND_CHANNEL_COUNT);
- resetChannelRange(firstChannel, firstChannel + channelCount);
- resetHeldNotesRange(firstChannel + 1, firstChannel + channelCount);
+ resetChannelRange(firstChannel + 1, firstChannel + channelCount);
+ clearActiveNotesRange(firstChannel + 1, firstChannel + channelCount);
sendMidiChannelReset(firstChannel + 1, firstChannel + channelCount);
}
@@ -95,7 +95,7 @@ void RSoundDemo::setVoiceVolume(int channelIndex, byte volume) {
}
bool RSoundDemo::isSequenceActive(int sequenceOffset) {
- return isSoundActive(loadData(sequenceOffset));
+ return isSoundPlaying(loadData(sequenceOffset));
}
const RSound1::CommandPtr RSound1::_commandList[42] = {
@@ -121,7 +121,7 @@ int RSound1::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
@@ -131,7 +131,7 @@ int RSound1::clampParam() {
void RSound1::method1() {
byte *pData = loadData(0x1166);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[0].playData(pData);
_channels[1].playData(loadData(0x13BC));
@@ -141,13 +141,13 @@ void RSound1::method1() {
}
int RSound1::command9() {
- playSound(0xAD4);
+ playSoundCh5To8(0xAD4);
return 0;
}
int RSound1::command10() {
byte *pData = loadData(0xCE4);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
_channels[0].playData(pData);
_channels[1].playData(loadData(0xD18));
_channels[2].playData(loadData(0xE9C));
@@ -184,13 +184,13 @@ int RSound1::command13() {
}
int RSound1::command14() {
- playSound(0x16C2);
+ playSoundCh5To8(0x16C2);
return 0;
}
int RSound1::command15() {
byte *pData = loadData(0xF3A);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[4].playData(pData);
_channels[5].playData(loadData(0x102A));
@@ -200,61 +200,61 @@ int RSound1::command15() {
}
int RSound1::command16() {
- playSound(0xADE);
+ playSoundCh5To8(0xADE);
return 0;
}
int RSound1::command17() {
- playSound(0xAE8);
+ playSoundCh5To8(0xAE8);
return 0;
}
int RSound1::command18() {
- playSound(0xAF2);
+ playSoundCh5To8(0xAF2);
return 0;
}
int RSound1::command19() {
command1();
- playSound(0xB04);
+ playSoundCh5To8(0xB04);
return 0;
}
int RSound1::command20() {
- playSound(0xB5E);
+ playSoundCh5To8(0xB5E);
return 0;
}
int RSound1::command21() {
- playSound(0xB4C);
+ playSoundCh5To8(0xB4C);
return 0;
}
int RSound1::command22() {
- playSound(0xB6E);
+ playSoundCh5To8(0xB6E);
return 0;
}
int RSound1::command23() {
byte *pData = loadData(0xB7A);
pData[6] ^= 0x1F;
- playSound(0xB7A);
+ playSoundCh5To8(0xB7A);
return 0;
}
int RSound1::command24() {
- playSound(0xB84);
+ playSoundCh5To8(0xB84);
return 0;
}
int RSound1::command25() {
- playSound(0xB8E);
+ playSoundCh5To8(0xB8E);
return 0;
}
int RSound1::command26() {
byte *pData = loadData(0xCCA);
- int v1 = (getRandomNumber() & 24) + 45;
+ int v1 = (generateRandomNumber() & 24) + 45;
pData[8] = v1;
int v2 = clampParam() + 64;
pData[5] = v2;
@@ -264,7 +264,7 @@ int RSound1::command26() {
int RSound1::command27() {
byte *pData = loadData(0xCBE);
- int v1 = (getRandomNumber() & 24) + 45;
+ int v1 = (generateRandomNumber() & 24) + 45;
pData[8] = v1;
int v2 = clampParam() + 64;
pData[5] = v2;
@@ -273,7 +273,7 @@ int RSound1::command27() {
}
int RSound1::command28() {
- playSound(0xB9E);
+ playSoundCh5To8(0xB9E);
return 0;
}
@@ -281,8 +281,8 @@ int RSound1::command29() {
byte *pData = loadData(0xC6C);
int v = (clampParam() >> 1) + 32;
pData[0xB] = v;
- if (!isSoundActive(pData))
- playSound(0xC6C);
+ if (!isSoundPlaying(pData))
+ playSoundCh5To8(0xC6C);
return 0;
}
@@ -290,13 +290,13 @@ int RSound1::command30() {
byte *pData = loadData(0xC80);
int v = clampParam() + 63;
pData[0xB] = v;
- if (!isSoundActive(pData))
- playSoundAny(0xC80);
+ if (!isSoundPlaying(pData))
+ playSoundCh1To8(0xC80);
return 0;
}
int RSound1::command31() {
- playSound(0xBBE);
+ playSoundCh5To8(0xBBE);
return 0;
}
@@ -305,56 +305,56 @@ int RSound1::command32() {
int half = clampParam() >> 1;
pData[0xB] = pData[0x17] = half + 68;
pData[0x11] = pData[0x1D] = half + 20;
- if (!isSoundActive(pData))
- playSoundAny(0xC96);
+ if (!isSoundPlaying(pData))
+ playSoundCh1To8(0xC96);
return 0;
}
int RSound1::command33() {
- playSound(0xBD0);
- playSound(0xBDA);
+ playSoundCh5To8(0xBD0);
+ playSoundCh5To8(0xBDA);
return 0;
}
int RSound1::command34() {
byte *pData = loadData(0xBE8);
- int v = (getRandomNumber() & 12) + 45;
+ int v = (generateRandomNumber() & 12) + 45;
pData[9] = v;
pData[0x10] = v + 36;
- playSound(0xBE8);
+ playSoundCh5To8(0xBE8);
return 0;
}
int RSound1::command35() {
- playSound(0xBFC);
- playSound(0xC0E);
- playSound(0xC20);
+ playSoundCh5To8(0xBFC);
+ playSoundCh5To8(0xC0E);
+ playSoundCh5To8(0xC20);
return 0;
}
int RSound1::command36() {
- playSound(0xC3E);
+ playSoundCh5To8(0xC3E);
return 0;
}
int RSound1::command37() {
byte *pData = loadData(0xC4C);
- int r = getRandomNumber() & 15;
+ int r = generateRandomNumber() & 15;
pData[6] = r + 42;
pData[3] = 62 - (r << 1);
- playSound(0xC4C);
+ playSoundCh5To8(0xC4C);
return 0;
}
int RSound1::command38() {
- playSoundAny(0xC56);
- playSound(0xC60);
+ playSoundCh1To8(0xC56);
+ playSoundCh5To8(0xC60);
return 0;
}
int RSound1::command39() {
byte *pData = loadData(0x1818);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
_channels[4].playData(pData);
_channels[5].playData(loadData(0x1848));
_channels[6].playData(loadData(0x1874));
@@ -365,12 +365,12 @@ int RSound1::command39() {
}
int RSound1::command40() {
- playSound(0xC34);
+ playSoundCh5To8(0xC34);
return 0;
}
int RSound1::command41() {
- playSound(0xCD6);
+ playSoundCh5To8(0xCD6);
return 0;
}
@@ -432,7 +432,7 @@ int RSoundDemo1::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
if (commandId <= 8)
return executeDemoCommonCommand(commandId);
@@ -496,7 +496,7 @@ int RSoundDemo1::command(int commandId, int param) {
break;
case 22: {
byte *data = sequenceData(0x0FCE);
- data[6] = (getRandomNumber() & 0x07) + 0x73;
+ data[6] = (generateRandomNumber() & 0x07) + 0x73;
startAnyVoice(0x0FCE);
break;
}
@@ -514,7 +514,7 @@ int RSoundDemo1::command(int commandId, int param) {
case 27: {
const int sequenceOffset = commandId == 26 ? 0x10F8 : 0x10EC;
byte *data = sequenceData(sequenceOffset);
- data[8] = (getRandomNumber() & 0x18) + 0x2D;
+ data[8] = (generateRandomNumber() & 0x18) + 0x2D;
data[5] = adjustedCommandParam() + 0x40;
startVoice(7, sequenceOffset);
break;
@@ -554,7 +554,7 @@ int RSoundDemo1::command(int commandId, int param) {
break;
case 34: {
byte *data = sequenceData(0x104C);
- data[9] = (getRandomNumber() & 0x0C) + 0x2D;
+ data[9] = (generateRandomNumber() & 0x0C) + 0x2D;
data[16] = data[9] + 0x24;
startAnyVoice(0x104C);
break;
@@ -618,7 +618,7 @@ int RSound2::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
@@ -634,7 +634,7 @@ int RSound2::command5() {
int RSound2::command9() {
byte *pData = loadData(0x103C);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[0].playData(pData);
_channels[1].playData(loadData(0x11B2));
@@ -645,7 +645,7 @@ int RSound2::command9() {
int RSound2::command10() {
byte *pData = loadData(0x132E);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[2].playData(pData);
_channels[8].playData(loadData(0x1384));
@@ -655,7 +655,7 @@ int RSound2::command10() {
int RSound2::command11() {
byte *pData = loadData(0x1548);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[2].playData(pData);
_channels[8].playData(loadData(0x1648));
@@ -667,29 +667,29 @@ int RSound2::command12() {
byte *pData = loadData(0xE52);
_pitchCycleCounter += 16;
pData[3] = _pitchCycleCounter & 0x7F;
- playSound(0xE52);
+ playSoundCh5To8(0xE52);
return 0;
}
int RSound2::command13() {
- playSound(0xE5C);
- playSound(0xE66);
+ playSoundCh5To8(0xE5C);
+ playSoundCh5To8(0xE66);
return 0;
}
int RSound2::command14() {
- playSound(0xE70);
- playSound(0xE8A);
+ playSoundCh5To8(0xE70);
+ playSoundCh5To8(0xE8A);
return 0;
}
int RSound2::command15() {
byte *pData = loadData(0x1DFC);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
- playSoundAny(0x1DFC);
- playSoundAny(0x222E);
- playSoundAny(0x2648);
+ playSoundCh1To8(0x1DFC);
+ playSoundCh1To8(0x222E);
+ playSoundCh1To8(0x2648);
_channels[8].playData(loadData(0x26A2));
}
return 0;
@@ -697,25 +697,25 @@ int RSound2::command15() {
int RSound2::command16() {
byte *pData = loadData(0x3456);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
- playSoundAny(0x3456);
- playSoundAny(0x3572);
- playSoundAny(0x367E);
- playSoundAny(0x37C6);
- playSoundAny(0x39AE);
- playSoundAny(0x3A3A);
+ playSoundCh1To8(0x3456);
+ playSoundCh1To8(0x3572);
+ playSoundCh1To8(0x367E);
+ playSoundCh1To8(0x37C6);
+ playSoundCh1To8(0x39AE);
+ playSoundCh1To8(0x3A3A);
}
return 0;
}
int RSound2::command17() {
byte *pData = loadData(0x3AC0);
- if (!isSoundActive(pData)) {
- playSound(0x3AC0);
- playSound(0x3C70);
- playSound(0x3E16);
- playSound(0x3FBE);
+ if (!isSoundPlaying(pData)) {
+ playSoundCh5To8(0x3AC0);
+ playSoundCh5To8(0x3C70);
+ playSoundCh5To8(0x3E16);
+ playSoundCh5To8(0x3FBE);
}
return 0;
}
@@ -724,177 +724,177 @@ int RSound2::command18() {
if (_channels[7]._deltaCounter)
return 0;
- int idx = (getRandomNumber() & 30) >> 1;
+ int idx = (generateRandomNumber() & 30) >> 1;
_channels[7].playData(loadData(_table1[idx]));
return 0;
}
int RSound2::command19() {
byte *pData = loadData(0x2A64);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
- playSoundAny(0x2A64);
- playSoundAny(0x2BE2);
- playSoundAny(0x2DAC);
- playSoundAny(0x2ECE);
- playSoundAny(0x3026);
- playSoundAny(0x30C2);
+ playSoundCh1To8(0x2A64);
+ playSoundCh1To8(0x2BE2);
+ playSoundCh1To8(0x2DAC);
+ playSoundCh1To8(0x2ECE);
+ playSoundCh1To8(0x3026);
+ playSoundCh1To8(0x30C2);
}
return 0;
}
int RSound2::command20() {
- playSound(0xF1E);
- playSound(0xF1E);
- playSound(0xF1E);
- playSound(0xF1E);
+ playSoundCh5To8(0xF1E);
+ playSoundCh5To8(0xF1E);
+ playSoundCh5To8(0xF1E);
+ playSoundCh5To8(0xF1E);
return 0;
}
int RSound2::command21() {
- playSound(0xF58);
+ playSoundCh5To8(0xF58);
return 0;
}
int RSound2::command22() {
- playSound(0xF44);
+ playSoundCh5To8(0xF44);
return 0;
}
int RSound2::command23() {
- playSound(0xEBA);
+ playSoundCh5To8(0xEBA);
return 0;
}
int RSound2::command24() {
- playSound(0xEB0);
+ playSoundCh5To8(0xEB0);
return 0;
}
int RSound2::command25() {
- playSound(0xEA6);
+ playSoundCh5To8(0xEA6);
return 0;
}
int RSound2::command26() {
- playSound(0xF4E);
+ playSoundCh5To8(0xF4E);
return 0;
}
int RSound2::command27() {
- Channel *ch = playSound(0xFAC);
+ Channel *ch = playSoundCh5To8(0xFAC);
if (ch)
ch->_innerLoopStart = loadData(0xFB8);
- ch = playSound(0xFB2);
+ ch = playSoundCh5To8(0xFB2);
if (ch)
ch->_innerLoopStart = loadData(0xFB8);
- playSound(0xFB8);
+ playSoundCh5To8(0xFB8);
return 0;
}
int RSound2::command28() {
byte *pData = loadData(0xEDA);
- int r = getRandomNumber();
+ int r = generateRandomNumber();
int v1 = r & 0x7F;
pData[7] = v1;
int v2 = (v1 & 0x0F) + 0x43;
pData[8] = v2;
int v3 = v2 + 0x0C;
pData[0xA] = v3;
- playSound(0xEDA);
+ playSoundCh5To8(0xEDA);
return 0;
}
int RSound2::command29() {
- playSoundAny(0xF80);
+ playSoundCh1To8(0xF80);
return 0;
}
int RSound2::command30() {
- playSound(0xF14);
+ playSoundCh5To8(0xF14);
byte *pData = loadData(0xF0A);
pData[3] = 40;
- playSound(0xF0A);
+ playSoundCh5To8(0xF0A);
return 0;
}
int RSound2::command31() {
byte *pData = loadData(0xF0A);
pData[3] = 0x18;
- playSound(0xF0A);
+ playSoundCh5To8(0xF0A);
return 0;
}
int RSound2::command32() {
- playSound(0xEC4);
+ playSoundCh5To8(0xEC4);
return 0;
}
int RSound2::command33() {
- playSound(0xED0);
+ playSoundCh5To8(0xED0);
return 0;
}
int RSound2::command34() {
- playSound(0xEE8);
+ playSoundCh5To8(0xEE8);
return 0;
}
int RSound2::command35() {
- playSound(0xEF8);
+ playSoundCh5To8(0xEF8);
return 0;
}
int RSound2::command36() {
- playSound(0xFF4);
- playSound(0x1008);
+ playSoundCh5To8(0xFF4);
+ playSoundCh5To8(0x1008);
return 0;
}
int RSound2::command37() {
- playSound(0xFCC);
+ playSoundCh5To8(0xFCC);
return 0;
}
int RSound2::command38() {
byte *pData = loadData(0x2B0E);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
- playSoundAny(0x2B0E);
- playSoundAny(0x2CD0);
- playSoundAny(0x2E46);
- playSoundAny(0x2F7C);
- playSoundAny(0x3074);
- playSoundAny(0x317E);
+ playSoundCh1To8(0x2B0E);
+ playSoundCh1To8(0x2CD0);
+ playSoundCh1To8(0x2E46);
+ playSoundCh1To8(0x2F7C);
+ playSoundCh1To8(0x3074);
+ playSoundCh1To8(0x317E);
}
return 0;
}
int RSound2::command39() {
- playSound(0xFDA);
+ playSoundCh5To8(0xFDA);
return 0;
}
int RSound2::command40() {
- playSound(0xFE6);
+ playSoundCh5To8(0xFE6);
return 0;
}
int RSound2::command41() {
- playSoundAny(0xF62);
+ playSoundCh1To8(0xF62);
return 0;
}
int RSound2::command42() {
- playSound(0xF92);
+ playSoundCh5To8(0xF92);
return 0;
}
int RSound2::command43() {
- playSound(0x1018);
- playSound(0x102A);
+ playSoundCh5To8(0x1018);
+ playSoundCh5To8(0x102A);
return 0;
}
@@ -928,14 +928,14 @@ int RSound3::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
Channel *RSound3::method1(int offset, byte value) {
byte *pData = loadData(offset);
pData[5] = value;
- return playSound(offset);
+ return playSoundCh5To8(offset);
}
void RSound3::resetUpperChannelsTail() {
@@ -971,7 +971,7 @@ int RSound3::command9() {
int RSound3::command10() {
byte *pData = loadData(0x14FE);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[0].playData(pData);
_channels[1].playData(loadData(0x1630));
@@ -990,7 +990,7 @@ void RSound3::setVariantByte(byte value) {
}
int RSound3::command11() {
- if (!isSoundActive(loadData(0x1AE6))) {
+ if (!isSoundPlaying(loadData(0x1AE6))) {
setVariantByte(0x64);
_channels[0].playData(loadData(0x1AE6));
_channels[1].playData(loadData(0x1E00));
@@ -1005,11 +1005,11 @@ int RSound3::command11() {
int RSound3::command13() {
command1();
- playSoundAny(0x1364);
- playSoundAny(0x1364);
- playSoundAny(0x1364);
- playSoundAny(0x1364);
- playSoundAny(0x1364);
+ playSoundCh1To8(0x1364);
+ playSoundCh1To8(0x1364);
+ playSoundCh1To8(0x1364);
+ playSoundCh1To8(0x1364);
+ playSoundCh1To8(0x1364);
return 0;
}
@@ -1058,7 +1058,7 @@ int RSound3::command16() {
if (_command16AltFlag) {
byte *pData = loadData(0x345E);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
_channels[0].playData(pData);
_channels[1].playData(loadData(0x364C));
_channels[2].playData(loadData(0x3806));
@@ -1066,7 +1066,7 @@ int RSound3::command16() {
}
} else {
byte *pData = loadData(0x3B26);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[0].playData(pData);
_channels[1].playData(loadData(0x3BD8));
@@ -1079,7 +1079,7 @@ int RSound3::command16() {
int RSound3::command17() {
byte *pData = loadData(0x3F5C);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[0].playData(pData);
_channels[1].playData(loadData(0x4022));
@@ -1101,42 +1101,42 @@ int RSound3::command18() {
}
int RSound3::command19() {
- if (!isSoundActive(loadData(0x1AE6)))
- playSound(0x12B4);
+ if (!isSoundPlaying(loadData(0x1AE6)))
+ playSoundCh5To8(0x12B4);
return 0;
}
int RSound3::command20() {
- if (!isSoundActive(loadData(0x1AE6)))
- playSound(0x1246);
+ if (!isSoundPlaying(loadData(0x1AE6)))
+ playSoundCh5To8(0x1246);
return 0;
}
int RSound3::command21() {
- if (!isSoundActive(loadData(0x1AE6))) {
- playSound(0x1232);
- playSound(0x123C);
+ if (!isSoundPlaying(loadData(0x1AE6))) {
+ playSoundCh5To8(0x1232);
+ playSoundCh5To8(0x123C);
}
return 0;
}
int RSound3::command22() {
- playSound(0x126E);
+ playSoundCh5To8(0x126E);
return 0;
}
int RSound3::command23() {
- if (!isSoundActive(loadData(0x1AE6))) {
- playSound(0x12D2);
- playSound(0x12E0);
+ if (!isSoundPlaying(loadData(0x1AE6))) {
+ playSoundCh5To8(0x12D2);
+ playSoundCh5To8(0x12E0);
}
return 0;
}
int RSound3::command24() {
- if (!isSoundActive(loadData(0x1AE6))) {
- playSound(0x11E2);
- playSound(0x120A);
+ if (!isSoundPlaying(loadData(0x1AE6))) {
+ playSoundCh5To8(0x11E2);
+ playSoundCh5To8(0x120A);
}
return 0;
}
@@ -1150,74 +1150,74 @@ int RSound3::command25() {
}
int RSound3::command26() {
- playSound(0x1252);
+ playSoundCh5To8(0x1252);
return 0;
}
int RSound3::command27x42() {
- playSound(0x14BE);
+ playSoundCh5To8(0x14BE);
return 0;
}
int RSound3::command28() {
byte *pData = loadData(0x12EE);
pData[3] = 0x4D;
- playSound(0x12EE);
+ playSoundCh5To8(0x12EE);
return 0;
}
int RSound3::command29() {
byte *pData = loadData(0x12EE);
pData[3] = 0x7F;
- playSound(0x12EE);
+ playSoundCh5To8(0x12EE);
return 0;
}
int RSound3::command30() {
- playSound(0x14B4);
- playSound(0x14AA);
+ playSoundCh5To8(0x14B4);
+ playSoundCh5To8(0x14AA);
return 0;
}
int RSound3::command31() {
- playSound(0x12F8);
- playSound(0x130E);
+ playSoundCh5To8(0x12F8);
+ playSoundCh5To8(0x130E);
return 0;
}
int RSound3::command32() {
- playSound(0x1472);
+ playSoundCh5To8(0x1472);
return 0;
}
int RSound3::command33() {
- playSound(0x147E);
+ playSoundCh5To8(0x147E);
return 0;
}
int RSound3::command34() {
- playSound(0x1488);
+ playSoundCh5To8(0x1488);
return 0;
}
int RSound3::command35() {
- playSound(0x1498);
+ playSoundCh5To8(0x1498);
return 0;
}
int RSound3::command36() {
- playSound(0x14DA);
- playSound(0x14EE);
+ playSoundCh5To8(0x14DA);
+ playSoundCh5To8(0x14EE);
return 0;
}
int RSound3::command37() {
- playSound(0x14CC);
+ playSoundCh5To8(0x14CC);
return 0;
}
int RSound3::command38() {
- playSound(0x133A);
+ playSoundCh5To8(0x133A);
return 0;
}
@@ -1226,7 +1226,7 @@ int RSound3::command39() {
pData[3] = 77;
_command3940Toggle ^= 4;
pData[6] = _command3940Toggle + 0x28;
- playSound(0x1346);
+ playSoundCh5To8(0x1346);
return 0;
}
@@ -1235,71 +1235,71 @@ int RSound3::command40() {
pData[3] = 47;
_command3940Toggle ^= 4;
pData[6] = _command3940Toggle + 0x28;
- playSound(0x1346);
+ playSoundCh5To8(0x1346);
return 0;
}
int RSound3::command41() {
- playSound(0x1184);
+ playSoundCh5To8(0x1184);
return 0;
}
int RSound3::command43() {
- playSound(0x1350);
- playSound(0x135A);
+ playSoundCh5To8(0x1350);
+ playSoundCh5To8(0x135A);
return 0;
}
int RSound3::command44() {
- playSound(0x12A0);
+ playSoundCh5To8(0x12A0);
return 0;
}
int RSound3::command45() {
- playSound(0x12AA);
+ playSoundCh5To8(0x12AA);
return 0;
}
int RSound3::command46() {
- playSound(0x13AA);
- playSound(0x13C6);
+ playSoundCh5To8(0x13AA);
+ playSoundCh5To8(0x13C6);
return 0;
}
int RSound3::command47x49() {
- playSound(0x13E6);
- playSound(0x13FE);
+ playSoundCh5To8(0x13E6);
+ playSoundCh5To8(0x13FE);
return 0;
}
int RSound3::command48() {
- playSound(0x141E);
+ playSoundCh5To8(0x141E);
return 0;
}
int RSound3::command50() {
- playSound(0x1436);
- playSound(0x144C);
+ playSoundCh5To8(0x1436);
+ playSoundCh5To8(0x144C);
return 0;
}
int RSound3::command51() {
- playSound(0x125C);
+ playSoundCh5To8(0x125C);
return 0;
}
int RSound3::command57() {
- playSound(0x1466);
+ playSoundCh5To8(0x1466);
return 0;
}
int RSound3::command59() {
- playSound(0x1324);
+ playSoundCh5To8(0x1324);
return 0;
}
int RSound3::command60() {
- playSound(0x132E);
+ playSoundCh5To8(0x132E);
return 0;
}
@@ -1332,7 +1332,7 @@ int RSound4::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
@@ -1397,60 +1397,60 @@ int RSound4::command10() {
}
int RSound4::command19() {
- playSound(0x1196);
+ playSoundCh5To8(0x1196);
return 0;
}
int RSound4::command20() {
- playSound(0x118A);
+ playSoundCh5To8(0x118A);
return 0;
}
int RSound4::command21() {
- playSound(0x1260);
- playSound(0x126A);
+ playSoundCh5To8(0x1260);
+ playSoundCh5To8(0x126A);
return 0;
}
int RSound4::command27() {
- playSound(0x1220);
+ playSoundCh5To8(0x1220);
return 0;
}
int RSound4::command30() {
- playSound(0x1216);
- playSound(0x120C);
+ playSoundCh5To8(0x1216);
+ playSoundCh5To8(0x120C);
return 0;
}
int RSound4::command32() {
- playSound(0x11D4);
+ playSoundCh5To8(0x11D4);
return 0;
}
int RSound4::command33() {
- playSound(0x11E0);
+ playSoundCh5To8(0x11E0);
return 0;
}
int RSound4::command34() {
- playSound(0x11EA);
+ playSoundCh5To8(0x11EA);
return 0;
}
int RSound4::command35() {
- playSound(0x11FA);
+ playSoundCh5To8(0x11FA);
return 0;
}
int RSound4::command36() {
- playSound(0x123C);
- playSound(0x1250);
+ playSoundCh5To8(0x123C);
+ playSoundCh5To8(0x1250);
return 0;
}
int RSound4::command37() {
- playSound(0x122E);
+ playSoundCh5To8(0x122E);
return 0;
}
@@ -1466,15 +1466,15 @@ int RSound4::command53() {
command1();
_callbackCounter = 56;
_callbackPeriod = 56;
- playSoundAny(0x1888);
- playSoundAny(0x18DE);
+ playSoundCh1To8(0x1888);
+ playSoundCh1To8(0x18DE);
return 0;
}
void RSound4::loadCommand54() {
_callbackFnPtr = nullptr;
- playSoundAny(0x18B2);
- playSoundAny(0x1904);
+ playSoundCh1To8(0x18B2);
+ playSoundCh1To8(0x1904);
}
int RSound4::command54() {
@@ -1484,7 +1484,7 @@ int RSound4::command54() {
void RSound4::loadCommand55() {
_callbackFnPtr = nullptr;
- playSoundAny(0x191E);
+ playSoundCh1To8(0x191E);
}
int RSound4::command55() {
@@ -1494,7 +1494,7 @@ int RSound4::command55() {
void RSound4::loadCommand56() {
_callbackFnPtr = nullptr;
- playSoundAny(0x185C);
+ playSoundCh1To8(0x185C);
}
int RSound4::command56() {
@@ -1503,7 +1503,7 @@ int RSound4::command56() {
}
int RSound4::command57() {
- playSound(0x11C8);
+ playSoundCh5To8(0x11C8);
return 0;
}
@@ -1514,7 +1514,7 @@ int RSound4::command58() {
}
int RSound4::command59() {
- playSound(0x11BE);
+ playSoundCh5To8(0x11BE);
return 0;
}
@@ -1543,33 +1543,33 @@ int RSound5::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
int RSound5::command9() {
- playSound(0x11C4);
+ playSoundCh5To8(0x11C4);
return 0;
}
int RSound5::command10() {
- playSound(0x1238);
+ playSoundCh5To8(0x1238);
return 0;
}
int RSound5::command11x24() {
- playSound(0x1196);
+ playSoundCh5To8(0x1196);
return 0;
}
int RSound5::command12x25() {
- playSound(0x1242);
+ playSoundCh5To8(0x1242);
return 0;
}
int RSound5::command13() {
- playSound(0x125E);
- playSound(0x1268);
+ playSoundCh5To8(0x125E);
+ playSoundCh5To8(0x1268);
return 0;
}
@@ -1589,66 +1589,66 @@ int RSound5::command15() {
}
int RSound5::command16() {
- playSound(0x129A);
- playSound(0x129A);
- playSound(0x129A);
- playSound(0x129A);
+ playSoundCh5To8(0x129A);
+ playSoundCh5To8(0x129A);
+ playSoundCh5To8(0x129A);
+ playSoundCh5To8(0x129A);
return 0;
}
int RSound5::command17() {
- playSound(0x11B4);
+ playSoundCh5To8(0x11B4);
return 0;
}
int RSound5::command18() {
- playSound(0x12E4);
- playSound(0x12F6);
- playSound(0x1308);
- playSound(0x131A);
+ playSoundCh5To8(0x12E4);
+ playSoundCh5To8(0x12F6);
+ playSoundCh5To8(0x1308);
+ playSoundCh5To8(0x131A);
return 0;
}
int RSound5::command19() {
- playSound(0x132C);
+ playSoundCh5To8(0x132C);
return 0;
}
int RSound5::command20() {
- playSound(0x1368);
+ playSoundCh5To8(0x1368);
return 0;
}
int RSound5::command21() {
- playSound(0x1388);
+ playSoundCh5To8(0x1388);
return 0;
}
int RSound5::command22() {
- playSound(0x139A);
+ playSoundCh5To8(0x139A);
return 0;
}
int RSound5::command23() {
- playSound(0x13AA);
- playSound(0x13AA);
- playSound(0x13AA);
- playSound(0x13AA);
+ playSoundCh5To8(0x13AA);
+ playSoundCh5To8(0x13AA);
+ playSoundCh5To8(0x13AA);
+ playSoundCh5To8(0x13AA);
return 0;
}
int RSound5::command26() {
- playSound(0x13D6);
+ playSoundCh5To8(0x13D6);
return 0;
}
int RSound5::command27() {
- playSound(0x13F0);
+ playSoundCh5To8(0x13F0);
return 0;
}
int RSound5::command28() {
- playSound(0x121C);
+ playSoundCh5To8(0x121C);
return 0;
}
@@ -1659,7 +1659,7 @@ void RSound5::loadTailChannels() {
int RSound5::command29() {
byte *pData = loadData(0x1488);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[0].playData(pData);
_channels[1].playData(loadData(0x1534));
@@ -1670,44 +1670,44 @@ int RSound5::command29() {
}
int RSound5::command30() {
- playSound(0x1212);
- playSound(0x1208);
+ playSoundCh5To8(0x1212);
+ playSoundCh5To8(0x1208);
return 0;
}
int RSound5::command31() {
- playSound(0x140A);
+ playSoundCh5To8(0x140A);
return 0;
}
int RSound5::command32() {
- playSound(0x11D0);
+ playSoundCh5To8(0x11D0);
return 0;
}
int RSound5::command33() {
- playSound(0x11DC);
+ playSoundCh5To8(0x11DC);
return 0;
}
int RSound5::command34() {
- playSound(0x11E6);
+ playSoundCh5To8(0x11E6);
return 0;
}
int RSound5::command35() {
- playSound(0x11F6);
+ playSoundCh5To8(0x11F6);
return 0;
}
int RSound5::command36() {
- playSound(0x1464);
- playSound(0x1478);
+ playSoundCh5To8(0x1464);
+ playSoundCh5To8(0x1478);
return 0;
}
int RSound5::command37() {
- playSound(0x122A);
+ playSoundCh5To8(0x122A);
return 0;
}
@@ -1718,13 +1718,13 @@ int RSound5::command38() {
}
int RSound5::command39() {
- playSound(0x141E);
- playSound(0x1428);
+ playSoundCh5To8(0x141E);
+ playSoundCh5To8(0x1428);
return 0;
}
int RSound5::command40() {
- playSound(0x1432);
+ playSoundCh5To8(0x1432);
return 0;
}
@@ -1756,7 +1756,7 @@ int RSound6::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
@@ -1794,74 +1794,74 @@ void RSound6::reloadCommand28() {
}
int RSound6::command9() {
- playSound(0x111C);
+ playSoundCh5To8(0x111C);
return 0;
}
int RSound6::command10() {
- playSound(0x1190);
+ playSoundCh5To8(0x1190);
return 0;
}
int RSound6::command11() {
- playSound(0x11A4);
- playSound(0x11A4);
- playSound(0x11A4);
- playSound(0x11A4);
+ playSoundCh5To8(0x11A4);
+ playSoundCh5To8(0x11A4);
+ playSoundCh5To8(0x11A4);
+ playSoundCh5To8(0x11A4);
return 0;
}
int RSound6::command12() {
- playSound(0x11C8);
+ playSoundCh5To8(0x11C8);
return 0;
}
int RSound6::command13x14() {
- playSound(0x11E8);
+ playSoundCh5To8(0x11E8);
return 0;
}
int RSound6::command15() {
- playSound(0x11F2);
- playSound(0x11F2);
- playSound(0x11F2);
- playSound(0x11F2);
+ playSoundCh5To8(0x11F2);
+ playSoundCh5To8(0x11F2);
+ playSoundCh5To8(0x11F2);
+ playSoundCh5To8(0x11F2);
return 0;
}
int RSound6::command16() {
- playSound(0x121E);
+ playSoundCh5To8(0x121E);
return 0;
}
int RSound6::command17() {
- playSound(0x1228);
- playSound(0x1228);
- playSound(0x1228);
- playSound(0x1228);
+ playSoundCh5To8(0x1228);
+ playSoundCh5To8(0x1228);
+ playSoundCh5To8(0x1228);
+ playSoundCh5To8(0x1228);
return 0;
}
int RSound6::command18() {
- playSound(0x1254);
+ playSoundCh5To8(0x1254);
return 0;
}
int RSound6::command19() {
- playSound(0x1266);
+ playSoundCh5To8(0x1266);
return 0;
}
int RSound6::command20() {
- playSound(0x1278);
+ playSoundCh5To8(0x1278);
return 0;
}
int RSound6::command21() {
_channels[4].playData(loadData(0x1282));
- playSound(0x1282);
- playSound(0x1282);
- playSound(0x12AA);
+ playSoundCh5To8(0x1282);
+ playSoundCh5To8(0x1282);
+ playSoundCh5To8(0x12AA);
return 0;
}
@@ -1874,7 +1874,7 @@ int RSound6::command22() {
}
int RSound6::command23() {
- playSound(0x1174);
+ playSoundCh5To8(0x1174);
return 0;
}
@@ -1894,7 +1894,7 @@ int RSound6::command25() {
}
int RSound6::command28() {
- if (isSoundActive(loadData(0x130A)))
+ if (isSoundPlaying(loadData(0x130A)))
return 0;
if (_channels[0]._deltaCounter && _channels[0]._soundData == loadData(0x1A38)) {
@@ -1930,7 +1930,7 @@ int RSound7::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
@@ -1944,17 +1944,17 @@ int RSound7::command9() {
}
int RSound7::command15() {
- playSound(0x125C);
+ playSoundCh5To8(0x125C);
return 0;
}
int RSound7::command16() {
- playSound(0x12DE);
+ playSoundCh5To8(0x12DE);
return 0;
}
int RSound7::command17() {
- playSound(0x12C2);
+ playSoundCh5To8(0x12C2);
return 0;
}
@@ -1974,23 +1974,23 @@ int RSound7::command19() {
}
int RSound7::command20() {
- playSound(0x1324);
- playSound(0x1324);
+ playSoundCh5To8(0x1324);
+ playSoundCh5To8(0x1324);
return 0;
}
int RSound7::command21() {
- playSound(0x1336);
+ playSoundCh5To8(0x1336);
return 0;
}
int RSound7::command22() {
- playSound(0x1340);
+ playSoundCh5To8(0x1340);
return 0;
}
int RSound7::command23() {
- playSound(0x12B4);
+ playSoundCh5To8(0x12B4);
return 0;
}
@@ -2022,39 +2022,39 @@ int RSound7::command27() {
}
int RSound7::command30() {
- playSound(0x12AA);
- playSound(0x12A0);
+ playSoundCh5To8(0x12AA);
+ playSoundCh5To8(0x12A0);
return 0;
}
int RSound7::command32() {
- playSound(0x1268);
+ playSoundCh5To8(0x1268);
return 0;
}
int RSound7::command33() {
- playSound(0x1274);
+ playSoundCh5To8(0x1274);
return 0;
}
int RSound7::command34() {
- playSound(0x127E);
+ playSoundCh5To8(0x127E);
return 0;
}
int RSound7::command35() {
- playSound(0x128E);
+ playSoundCh5To8(0x128E);
return 0;
}
int RSound7::command36() {
- playSound(0x1358);
- playSound(0x136C);
+ playSoundCh5To8(0x1358);
+ playSoundCh5To8(0x136C);
return 0;
}
int RSound7::command37() {
- playSound(0x134A);
+ playSoundCh5To8(0x134A);
return 0;
}
@@ -2082,12 +2082,12 @@ int RSound8::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
int RSound8::command9() {
- playSound(0x10BA);
+ playSoundCh5To8(0x10BA);
return 0;
}
@@ -2100,20 +2100,20 @@ int RSound8::command10() {
}
int RSound8::command11() {
- playSound(0x1194);
+ playSoundCh5To8(0x1194);
return 0;
}
int RSound8::command12() {
- playSound(0x11B2);
+ playSoundCh5To8(0x11B2);
return 0;
}
int RSound8::command13() {
- playSound(0x11D0);
- playSound(0x11D0);
- playSound(0x11D0);
- playSound(0x11D0);
+ playSoundCh5To8(0x11D0);
+ playSoundCh5To8(0x11D0);
+ playSoundCh5To8(0x11D0);
+ playSoundCh5To8(0x11D0);
return 0;
}
@@ -2122,10 +2122,10 @@ void RSound8::setCommand1415Variant(byte v1, byte v2) {
pData[3] = v1;
pData[6] = v2;
pData[9] = v2;
- playSound(0x1204);
- playSound(0x1204);
- playSound(0x1204);
- playSound(0x1204);
+ playSoundCh5To8(0x1204);
+ playSoundCh5To8(0x1204);
+ playSoundCh5To8(0x1204);
+ playSoundCh5To8(0x1204);
}
int RSound8::command14() {
@@ -2139,38 +2139,38 @@ int RSound8::command15() {
}
int RSound8::command16() {
- playSound(0x112E);
- playSound(0x112E);
+ playSoundCh5To8(0x112E);
+ playSoundCh5To8(0x112E);
return 0;
}
int RSound8::command17() {
- playSound(0x1234);
+ playSoundCh5To8(0x1234);
return 0;
}
int RSound8::command18() {
- playSound(0x1244);
+ playSoundCh5To8(0x1244);
return 0;
}
int RSound8::command19() {
- playSound(0x1254);
+ playSoundCh5To8(0x1254);
return 0;
}
int RSound8::command20() {
- playSound(0x125E);
+ playSoundCh5To8(0x125E);
return 0;
}
int RSound8::command21() {
- playSound(0x126E);
+ playSoundCh5To8(0x126E);
return 0;
}
int RSound8::command22() {
- playSound(0x1278);
+ playSoundCh5To8(0x1278);
return 0;
}
@@ -2183,28 +2183,28 @@ int RSound8::command23() {
}
int RSound8::command24() {
- playSound(0x12B4);
+ playSoundCh5To8(0x12B4);
return 0;
}
int RSound8::command25() {
- playSound(0x12CA);
+ playSoundCh5To8(0x12CA);
return 0;
}
int RSound8::command26() {
- playSound(0x12DC);
+ playSoundCh5To8(0x12DC);
return 0;
}
int RSound8::command27() {
- playSound(0x1112);
+ playSoundCh5To8(0x1112);
return 0;
}
int RSound8::command28() {
byte *pData = loadData(0x130A);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[0].playData(pData);
_channels[1].playData(loadData(0x1480));
@@ -2215,7 +2215,7 @@ int RSound8::command28() {
int RSound8::command29() {
byte *pData = loadData(0x15FC);
- if (!isSoundActive(pData)) {
+ if (!isSoundPlaying(pData)) {
command1();
_channels[2].playData(pData);
_channels[8].playData(loadData(0x1652));
@@ -2224,44 +2224,44 @@ int RSound8::command29() {
}
int RSound8::command30() {
- playSound(0x1108);
- playSound(0x10FE);
+ playSoundCh5To8(0x1108);
+ playSoundCh5To8(0x10FE);
return 0;
}
int RSound8::command31() {
- playSound(0x1140);
+ playSoundCh5To8(0x1140);
return 0;
}
int RSound8::command32() {
- playSound(0x10C6);
+ playSoundCh5To8(0x10C6);
return 0;
}
int RSound8::command33() {
- playSound(0x10D2);
+ playSoundCh5To8(0x10D2);
return 0;
}
int RSound8::command34() {
- playSound(0x10DC);
+ playSoundCh5To8(0x10DC);
return 0;
}
int RSound8::command35() {
- playSound(0x10EC);
+ playSoundCh5To8(0x10EC);
return 0;
}
int RSound8::command36() {
- playSound(0x12E6);
- playSound(0x12FA);
+ playSoundCh5To8(0x12E6);
+ playSoundCh5To8(0x12FA);
return 0;
}
int RSound8::command37() {
- playSound(0x1120);
+ playSoundCh5To8(0x1120);
return 0;
}
@@ -2295,7 +2295,7 @@ int RSound9::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
return (this->*_commandList[commandId])();
}
@@ -2374,76 +2374,76 @@ int RSound9::command17() {
}
int RSound9::command18() {
- playSound(0x3248);
+ playSoundCh5To8(0x3248);
return 0;
}
int RSound9::command19() {
- playSound(0x3262);
+ playSoundCh5To8(0x3262);
return 0;
}
int RSound9::command20() {
- int v = (getRandomNumber() & 24) + 77;
+ int v = (generateRandomNumber() & 24) + 77;
byte *pData = loadData(0x3284);
pData[6] = v & 0x7F;
- playSound(0x3284);
+ playSoundCh5To8(0x3284);
return 0;
}
int RSound9::command21() {
byte *pData = loadData(0x3298);
pData[9] = 70;
- if (!isSoundActive(pData))
- playSound(0x3298);
+ if (!isSoundPlaying(pData))
+ playSoundCh5To8(0x3298);
return 0;
}
int RSound9::command22() {
byte *pData = loadData(0x3298);
pData[9] = 45;
- if (!isSoundActive(pData))
- playSound(0x3298);
+ if (!isSoundPlaying(pData))
+ playSoundCh5To8(0x3298);
return 0;
}
int RSound9::command23() {
- Channel *chan = playSound(0x32B0);
+ Channel *chan = playSoundCh5To8(0x32B0);
if (chan)
chan->_innerLoopStart = loadData(0x32CE);
- chan = playSound(0x32B6);
+ chan = playSoundCh5To8(0x32B6);
if (chan)
chan->_innerLoopStart = loadData(0x32CE);
- chan = playSound(0x32C8);
+ chan = playSoundCh5To8(0x32C8);
if (chan)
chan->_innerLoopStart = loadData(0x32CE);
return 0;
}
int RSound9::command24() {
- playSound(0x32E0);
+ playSoundCh5To8(0x32E0);
return 0;
}
int RSound9::command25() {
- playSound(0x32F6);
+ playSoundCh5To8(0x32F6);
return 0;
}
int RSound9::command26() {
- playSound(0x331A);
+ playSoundCh5To8(0x331A);
return 0;
}
int RSound9::command27() {
- playSound(0x3332);
+ playSoundCh5To8(0x3332);
return 0;
}
int RSound9::command28() {
- int v = (getRandomNumber() & 28) + 15;
+ int v = (generateRandomNumber() & 28) + 15;
byte *pData = loadData(0x334A);
pData[6] = v & 0x7F;
_channels[7].playData(pData);
@@ -2451,32 +2451,32 @@ int RSound9::command28() {
}
int RSound9::command29() {
- int v = (getRandomNumber() & 12) + 33;
+ int v = (generateRandomNumber() & 12) + 33;
byte *pData = loadData(0x335E);
pData[6] = v & 0x7F;
- playSound(0x335E);
+ playSoundCh5To8(0x335E);
return 0;
}
int RSound9::command30() {
- playSound(0x3386);
+ playSoundCh5To8(0x3386);
return 0;
}
int RSound9::command31() {
- playSound(0x3396);
- playSound(0x33A4);
- playSound(0x33B2);
+ playSoundCh5To8(0x3396);
+ playSoundCh5To8(0x33A4);
+ playSoundCh5To8(0x33B2);
return 0;
}
int RSound9::command32() {
- playSound(0x33C0);
+ playSoundCh5To8(0x33C0);
return 0;
}
int RSound9::command33() {
- playSound(0x33CA);
+ playSoundCh5To8(0x33CA);
return 0;
}
@@ -2498,28 +2498,28 @@ int RSound9::command34() {
}
int RSound9::command35() {
- playSound(0x344C);
+ playSoundCh5To8(0x344C);
return 0;
}
int RSound9::command36() {
- playSound(0x334A);
+ playSoundCh5To8(0x334A);
- Channel *chan = playSound(0x32C2);
+ Channel *chan = playSoundCh5To8(0x32C2);
if (chan)
chan->_innerLoopStart = loadData(0x3378);
- chan = playSound(0x32BC);
+ chan = playSoundCh5To8(0x32BC);
if (chan)
chan->_innerLoopStart = loadData(0x3368);
return 0;
}
int RSound9::command37() {
- int v = (getRandomNumber() & 2) + 72;
+ int v = (generateRandomNumber() & 2) + 72;
byte *pData = loadData(0x349C);
pData[6] = v & 0x7F;
- playSound(0x349C);
+ playSoundCh5To8(0x349C);
return 0;
}
@@ -2650,7 +2650,7 @@ int RSound9::command48() {
byte *pData = loadData(0x34B0);
pData[6] ^= 0x1F;
pData[0xA] ^= 0x1F;
- playSound(0x34B0);
+ playSoundCh5To8(0x34B0);
return 0;
}
@@ -2744,7 +2744,7 @@ int RSoundDemo9::command(int commandId, int param) {
return 0;
_commandParam = param;
- _frameCounter = 0;
+ _ticksSinceLastCommand = 0;
if (commandId <= 8)
return executeDemoCommonCommand(commandId);
@@ -2781,7 +2781,7 @@ int RSoundDemo9::command(int commandId, int param) {
break;
case 20: {
byte *data = sequenceData(0x12F6);
- data[6] = (byte)(((getRandomNumber() & 0x38) + 0x4D) & 0x7F);
+ data[6] = (byte)(((generateRandomNumber() & 0x38) + 0x4D) & 0x7F);
startEffectVoice(0x12F6);
break;
}
@@ -2816,13 +2816,13 @@ int RSoundDemo9::command(int commandId, int param) {
break;
case 28: {
byte *data = sequenceData(0x13BC);
- data[6] = (byte)(((getRandomNumber() & 0x1C) + 0x0F) & 0x7F);
+ data[6] = (byte)(((generateRandomNumber() & 0x1C) + 0x0F) & 0x7F);
startEffectVoice(0x13BC);
break;
}
case 29: {
byte *data = sequenceData(0x13D0);
- data[6] = (byte)(((getRandomNumber() & 0x0C) + 0x21) & 0x7F);
+ data[6] = (byte)(((generateRandomNumber() & 0x0C) + 0x21) & 0x7F);
startEffectVoice(0x13D0);
break;
}
@@ -2865,7 +2865,7 @@ int RSoundDemo9::command(int commandId, int param) {
}
case 37: {
byte *data = sequenceData(0x150E);
- data[6] = (byte)(((getRandomNumber() & 0x02) + 0x48) & 0x7F);
+ data[6] = (byte)(((generateRandomNumber() & 0x02) + 0x48) & 0x7F);
startEffectVoice(0x150E);
break;
}
diff --git a/engines/mads/nebular/sound/rsound_nebular.h b/engines/mads/nebular/sound/rsound_nebular.h
index e0cd91de427..c6ea4b15f20 100644
--- a/engines/mads/nebular/sound/rsound_nebular.h
+++ b/engines/mads/nebular/sound/rsound_nebular.h
@@ -59,7 +59,7 @@ private:
/**
* Shared loader for command11/12/13 - matches method1 in the
- * disassembly (isSoundActive-gated command1() + 4-channel load).
+ * disassembly (isSoundPlaying-gated command1() + 4-channel load).
*/
void method1();
@@ -243,7 +243,7 @@ private:
/**
* Shared tail used by both command1
* (falls through into it after calling command3()) and command5
- * (jumps straight into it after its isSoundActive gate). Enables
+ * (jumps straight into it after its isSoundPlaying gate). Enables
* channels 5-8 (1-based; indices 4-7) - notably never reaches
* channel 9.
*/
diff --git a/engines/mads/nebular/sound/sound.cpp b/engines/mads/nebular/sound/sound.cpp
index 5b4375c1acf..3ec45274e88 100644
--- a/engines/mads/nebular/sound/sound.cpp
+++ b/engines/mads/nebular/sound/sound.cpp
@@ -43,6 +43,17 @@ RexSoundManager::RexSoundManager(Audio::Mixer *mixer, bool &soundFlag,
"falling back to AdLib");
}
}
+ if (_driverType == SOUND_MT32) {
+ // TODO Move to SoundManager superclass when other sound drivers have been reworked
+ _midiDriver = new MidiDriver_MT32GM(MusicType::MT_MT32);
+ int returnCode;
+ returnCode = _midiDriver->open();
+ if (returnCode != 0)
+ error("SoundManager - Failed to open MIDI music driver - error code %d.", returnCode);
+
+ _driverCallbackDelta = _midiDriver->getBaseTempo();
+ _midiDriver->setTimerCallback(this, &timerCallback);
+ }
}
void RexSoundManager::validate() {
More information about the Scummvm-git-logs
mailing list