aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen/music.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/xeen/music.cpp')
-rw-r--r--engines/xeen/music.cpp52
1 files changed, 36 insertions, 16 deletions
diff --git a/engines/xeen/music.cpp b/engines/xeen/music.cpp
index 19a836b12f..ef6bb6237a 100644
--- a/engines/xeen/music.cpp
+++ b/engines/xeen/music.cpp
@@ -34,7 +34,7 @@ namespace Xeen {
MusicDriver::MusicDriver() : _musicPlaying(false), _fxPlaying(false),
_musCountdownTimer(0), _fxCountdownTimer(0), _musDataPtr(nullptr),
_fxDataPtr(nullptr), _fxStartPtr(nullptr), _musStartPtr(nullptr),
- _exclude7(0), _frameCtr(0) {
+ _exclude7(false), _frameCtr(0) {
_channels.resize(CHANNEL_COUNT);
}
@@ -204,13 +204,21 @@ void MusicDriver::playFX(uint effectId, const byte *data) {
_fxDataPtr = _fxStartPtr = data;
_fxCountdownTimer = 0;
_channels[7]._changeFrequency = _channels[8]._changeFrequency = false;
- stopFX();
+ resetFX();
_fxPlaying = true;
}
debugC(1, kDebugSound, "Starting FX %d", effectId);
}
+void MusicDriver::stopFX() {
+ if (_fxPlaying) {
+ resetFX();
+ _fxPlaying = false;
+ _fxStartPtr = _fxDataPtr = nullptr;
+ }
+}
+
void MusicDriver::playSong(const byte *data) {
_musDataPtr = _musStartPtr = data;
_musSubroutines.clear();
@@ -283,7 +291,7 @@ void AdlibMusicDriver::initialize() {
write(0xBD, 0);
resetFrequencies();
- AdlibMusicDriver::stopFX();
+ AdlibMusicDriver::resetFX();
}
void AdlibMusicDriver::playFX(uint effectId, const byte *data) {
@@ -387,7 +395,7 @@ void AdlibMusicDriver::pausePostProcess() {
}
}
-void AdlibMusicDriver::stopFX() {
+void AdlibMusicDriver::resetFX() {
if (!_exclude7) {
_channels[7]._frequency = 0;
setFrequency(7, 0);
@@ -399,7 +407,6 @@ void AdlibMusicDriver::stopFX() {
setFrequency(8, 0);
_channels[8]._volume = 63;
setOutputLevel(8, 63);
- _fxPlaying = false;
}
void AdlibMusicDriver::resetFrequencies() {
@@ -604,7 +611,8 @@ bool AdlibMusicDriver::fxStartNote(const byte *&srcP, byte param) {
debugC(3, kDebugSound, "fxStartNote %x -> %x", note, freq);
setFrequency(param, freq);
- _channels[param]._frequency = freq | 0x2000;
+ freq |= 0x2000;
+ _channels[param]._frequency = freq;
setFrequency(param, freq);
} else {
++srcP;
@@ -626,7 +634,7 @@ bool AdlibMusicDriver::fxPlayInstrument(const byte *&srcP, byte param) {
byte instrument = *srcP++;
debugC(3, kDebugSound, "fxPlayInstrument %d, %d", param, instrument);
- if (_exclude7 != 2 || param != 7)
+ if (!_exclude7 || param != 7)
playInstrument(param, _fxInstrumentPtrs[instrument]);
return false;
@@ -667,27 +675,35 @@ void Music::loadEffectsData() {
return;
// Stop any prior FX
- _musicDriver->stopFX();
-
+ stopFX();
+ delete[] _effectsData;
+ _archiveType = File::_currentArchive;
- // Load in the entire driver so we have quick access to the effects data
+ // Load in an entire driver so we have quick access to the effects data
// that's hardcoded within it
- File file("promus");
+ File file("blastmus");
byte *effectsData = new byte[file.size()];
file.seek(0);
file.read(effectsData, file.size());
file.close();
_effectsData = effectsData;
+ // Locate the playFX routine
+ const byte *playFX = effectsData + READ_LE_UINT16(effectsData + 10) + 12;
+ assert(READ_BE_UINT16(playFX + 28) == 0x81FB);
+ uint numEffects = READ_LE_UINT16(playFX + 30);
+
+ assert(READ_BE_UINT16(playFX + 36) == 0x8B87);
+ const byte *table = effectsData + READ_LE_UINT16(playFX + 38);
+
// Extract the effects offsets
- _effectsOffsets.resize(180);
- const int EFFECTS_OFFSET = 0x91D;
- for (int idx = 0; idx < 180; ++idx)
- _effectsOffsets[idx] = READ_LE_UINT16(&effectsData[EFFECTS_OFFSET + idx * 2]);
+ _effectsOffsets.resize(numEffects);
+ for (uint idx = 0; idx < numEffects; ++idx)
+ _effectsOffsets[idx] = READ_LE_UINT16(&table[idx * 2]);
}
void Music::playFX(uint effectId) {
- _musicDriver->stopFX();
+ stopFX();
loadEffectsData();
if (effectId < _effectsOffsets.size()) {
@@ -696,6 +712,10 @@ void Music::playFX(uint effectId) {
}
}
+void Music::stopFX() {
+ _musicDriver->stopFX();
+}
+
int Music::songCommand(uint commandId, byte volume) {
int result = _musicDriver->songCommand(commandId, volume);
if (commandId == STOP_SONG) {