aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Montoir2007-11-18 20:27:31 +0000
committerGregory Montoir2007-11-18 20:27:31 +0000
commitc76c6e22567b7b2f89acdf53cb73ed2cf9cac2d3 (patch)
treebaed116dbdea13789a3f563ea225965bf0fec6f1
parent9e58b0253d40efb2513755e7f09b17e12fdecdc8 (diff)
downloadscummvm-rg350-c76c6e22567b7b2f89acdf53cb73ed2cf9cac2d3.tar.gz
scummvm-rg350-c76c6e22567b7b2f89acdf53cb73ed2cf9cac2d3.tar.bz2
scummvm-rg350-c76c6e22567b7b2f89acdf53cb73ed2cf9cac2d3.zip
added rjp1 module specific pattern playback
svn-id: r29559
-rw-r--r--engines/queen/sound.cpp29
-rw-r--r--engines/queen/sound.h4
-rw-r--r--sound/mods/rjp1.cpp175
-rw-r--r--sound/mods/rjp1.h2
4 files changed, 141 insertions, 69 deletions
diff --git a/engines/queen/sound.cpp b/engines/queen/sound.cpp
index 8b82f715ca..6f7bbc4b2c 100644
--- a/engines/queen/sound.cpp
+++ b/engines/queen/sound.cpp
@@ -541,7 +541,7 @@ void AmigaSound::updateMusic() {
if (_fluteCount > 0 && (_lastOverride == 40 || _lastOverride == 3)) {
--_fluteCount;
if (_fluteCount == 0) {
- playRandomPatternJungle();
+ playPattern("JUNG", 5 + _vm->randomizer.getRandomNumber(6));
_fluteCount = 100;
}
}
@@ -564,8 +564,8 @@ void AmigaSound::playSound(const char *base) {
}
}
-void AmigaSound::playModule(const char *base, int song) {
- debug(7, "AmigaSound::playModule(%s, %d)", base, song);
+Audio::AudioStream *AmigaSound::loadModule(const char *base, int num) {
+ debug(7, "AmigaSound::loadModule(%s, %d)", base, num);
char name[20];
// load song/pattern data
@@ -580,20 +580,29 @@ void AmigaSound::playModule(const char *base, int song) {
uint8 *insData = _vm->resource()->loadFile(name, 0, &insDataSize);
Common::MemoryReadStream insStr(insData, insDataSize);
- _mixer->stopHandle(_modHandle);
- Audio::AudioStream *stream = Audio::makeRjp1Stream(&sngStr, &insStr, song, _mixer->getOutputRate());
- if (stream) {
- _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_modHandle, stream);
- }
+ Audio::AudioStream *stream = Audio::makeRjp1Stream(&sngStr, &insStr, num, _mixer->getOutputRate());
delete[] sngData;
delete[] insData;
+ return stream;
+}
+
+void AmigaSound::playModule(const char *base, int song) {
+ _mixer->stopHandle(_modHandle);
+ Audio::AudioStream *stream = loadModule(base, song);
+ if (stream) {
+ _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_modHandle, stream);
+ }
_fanfareCount = 0;
}
-void AmigaSound::playRandomPatternJungle() {
- // XXX pickup a pattern (songData[4],songData[6]) between 5 and 11 from JUNG.SNG and play it
+void AmigaSound::playPattern(const char *base, int pattern) {
+ _mixer->stopHandle(_patHandle);
+ Audio::AudioStream *stream = loadModule(base, -pattern);
+ if (stream) {
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_patHandle, stream);
+ }
}
bool AmigaSound::playSpecialSfx(int16 sfx) {
diff --git a/engines/queen/sound.h b/engines/queen/sound.h
index 3906167193..e2a279c09b 100644
--- a/engines/queen/sound.h
+++ b/engines/queen/sound.h
@@ -170,13 +170,15 @@ public:
protected:
void playSound(const char *base);
+ Audio::AudioStream *loadModule(const char *base, int song);
void playModule(const char *base, int song);
- void playRandomPatternJungle();
+ void playPattern(const char *base, int pattern);
bool playSpecialSfx(int16 sfx);
int16 _fanfareRestore;
int _fanfareCount, _fluteCount;
Audio::SoundHandle _modHandle;
+ Audio::SoundHandle _patHandle;
Audio::SoundHandle _sfxHandle;
};
diff --git a/sound/mods/rjp1.cpp b/sound/mods/rjp1.cpp
index 59b8833607..0eb6b0d16b 100644
--- a/sound/mods/rjp1.cpp
+++ b/sound/mods/rjp1.cpp
@@ -70,6 +70,7 @@ struct Rjp1Channel {
uint16 len;
uint16 repeatPos;
uint16 repeatLen;
+ bool isSfx;
};
class Rjp1 : public Paula {
@@ -90,6 +91,7 @@ public:
bool load(Common::SeekableReadStream *songData, Common::SeekableReadStream *instrumentsData);
void unload();
+ void startPattern(int ch, int pat);
void startSong(int song);
protected:
@@ -98,6 +100,8 @@ protected:
void turnOffChannel(Rjp1Channel *channel);
void playChannel(Rjp1Channel *channel);
void turnOnChannel(Rjp1Channel *channel);
+ bool executeSfxSequenceOp(Rjp1Channel *channel, uint8 code, const uint8 *&p);
+ bool executeSongSequenceOp(Rjp1Channel *channel, uint8 code, const uint8 *&p);
void playSongSequence(Rjp1Channel *channel);
void modulateVolume(Rjp1Channel *channel);
void modulatePeriod(Rjp1Channel *channel);
@@ -186,6 +190,18 @@ void Rjp1::unload() {
memset(_channelsTable, 0, sizeof(_channelsTable));
}
+void Rjp1::startPattern(int ch, int pat) {
+ Rjp1Channel *channel = &_channelsTable[ch];
+ _vars.activeChannelsMask |= 1 << ch;
+ channel->sequenceData = READ_BE_UINT32(_vars.songData[4] + pat * 4) + _vars.songData[6];
+ channel->loopSeqCount = 6;
+ channel->loopSeqCur = channel->loopSeq2Cur = 1;
+ channel->active = true;
+ channel->isSfx = true;
+ // "start" Paula audiostream
+ startPaula();
+}
+
void Rjp1::startSong(int song) {
if (song == 0 || song >= _vars.subsongsCount) {
warning("Invalid subsong number %d, defaulting to 1", song);
@@ -241,6 +257,98 @@ void Rjp1::turnOnChannel(Rjp1Channel *channel) {
}
}
+bool Rjp1::executeSfxSequenceOp(Rjp1Channel *channel, uint8 code, const uint8 *&p) {
+ bool loop = true;
+ switch (code & 7) {
+ case 0:
+ _vars.activeChannelsMask &= ~(1 << _vars.currentChannel);
+ loop = false;
+ stopPaula();
+ break;
+ case 1:
+ setRelease(channel);
+ loop = false;
+ break;
+ case 2:
+ channel->loopSeqCount = *p++;
+ break;
+ case 3:
+ channel->loopSeq2Count = *p++;
+ break;
+ case 4:
+ code = *p++;
+ if (code != 0) {
+ setupInstrument(channel, code);
+ }
+ break;
+ case 7:
+ loop = false;
+ break;
+ }
+ return loop;
+}
+
+bool Rjp1::executeSongSequenceOp(Rjp1Channel *channel, uint8 code, const uint8 *&p) {
+ bool loop = true;
+ const uint8 *offs;
+ switch (code & 7) {
+ case 0:
+ offs = channel->sequenceOffsets;
+ channel->loopSeq2Count = 1;
+ while (1) {
+ code = *offs++;
+ if (code != 0) {
+ channel->sequenceOffsets = offs;
+ p = READ_BE_UINT32(_vars.songData[4] + code * 4) + _vars.songData[6];
+ break;
+ } else {
+ code = offs[0];
+ if (code == 0) {
+ p = 0;
+ channel->active = false;
+ _vars.activeChannelsMask &= ~(1 << _vars.currentChannel);
+ loop = false;
+ break;
+ } else if (code & 0x80) {
+ code = offs[1];
+ offs = READ_BE_UINT32(_vars.songData[3] + code * 4) + _vars.songData[5];
+ } else {
+ offs -= code;
+ }
+ }
+ }
+ break;
+ case 1:
+ setRelease(channel);
+ loop = false;
+ break;
+ case 2:
+ channel->loopSeqCount = *p++;
+ break;
+ case 3:
+ channel->loopSeq2Count = *p++;
+ break;
+ case 4:
+ code = *p++;
+ if (code != 0) {
+ setupInstrument(channel, code);
+ }
+ break;
+ case 5:
+ channel->volumeScale = *p++;
+ break;
+ case 6:
+ channel->freqStep = *p++;
+ channel->freqInc = READ_BE_UINT32(p); p += 4;
+ channel->freqInit = 0;
+ break;
+ case 7:
+ loop = false;
+ break;
+ }
+ return loop;
+}
+
void Rjp1::playSongSequence(Rjp1Channel *channel) {
const uint8 *p = channel->sequenceData;
--channel->loopSeqCur;
@@ -251,61 +359,10 @@ void Rjp1::playSongSequence(Rjp1Channel *channel) {
do {
uint8 code = *p++;
if (code & 0x80) {
- const uint8 *offs;
- switch (code & 7) {
- case 0:
- offs = channel->sequenceOffsets;
- channel->loopSeq2Count = 1;
- while (1) {
- code = *offs++;
- if (code != 0) {
- channel->sequenceOffsets = offs;
- p = READ_BE_UINT32(_vars.songData[4] + code * 4) + _vars.songData[6];
- break;
- } else {
- code = offs[0];
- if (code == 0) {
- p = 0;
- channel->active = false;
- _vars.activeChannelsMask &= ~(1 << _vars.currentChannel);
- loop = false;
- break;
- } else if (code & 0x80) {
- code = offs[1];
- offs = READ_BE_UINT32(_vars.songData[3] + code * 4) + _vars.songData[5];
- } else {
- offs -= code;
- }
- }
- }
- break;
- case 1:
- setRelease(channel);
- loop = false;
- break;
- case 2:
- channel->loopSeqCount = *p++;
- break;
- case 3:
- channel->loopSeq2Count = *p++;
- break;
- case 4:
- code = *p++;
- if (code != 0) {
- setupInstrument(channel, code);
- }
- break;
- case 5:
- channel->volumeScale = *p++;
- break;
- case 6:
- channel->freqStep = *p++;
- channel->freqInc = READ_BE_UINT32(p); p += 4;
- channel->freqInit = 0;
- break;
- case 7:
- loop = false;
- break;
+ if (channel->isSfx) {
+ loop = executeSfxSequenceOp(channel, code, p);
+ } else {
+ loop = executeSongSequenceOp(channel, code, p);
}
} else {
code >>= 1;
@@ -507,10 +564,14 @@ const int16 Rjp1::_periodsTable[] = {
const int Rjp1::_periodsCount = ARRAYSIZE(_periodsTable);
-AudioStream *makeRjp1Stream(Common::SeekableReadStream *songData, Common::SeekableReadStream *instrumentsData, int song, int rate, bool stereo) {
+AudioStream *makeRjp1Stream(Common::SeekableReadStream *songData, Common::SeekableReadStream *instrumentsData, int num, int rate, bool stereo) {
Rjp1 *stream = new Rjp1(rate, stereo);
if (stream->load(songData, instrumentsData)) {
- stream->startSong(song);
+ if (num < 0) {
+ stream->startPattern(3, -num);
+ } else {
+ stream->startSong(num);
+ }
return stream;
}
delete stream;
diff --git a/sound/mods/rjp1.h b/sound/mods/rjp1.h
index d263d11897..2fb54d88a6 100644
--- a/sound/mods/rjp1.h
+++ b/sound/mods/rjp1.h
@@ -32,7 +32,7 @@ namespace Audio {
class AudioStream;
-AudioStream *makeRjp1Stream(Common::SeekableReadStream *songData, Common::SeekableReadStream *instrumentsData, int song, int rate = 44100, bool stereo = true);
+AudioStream *makeRjp1Stream(Common::SeekableReadStream *songData, Common::SeekableReadStream *instrumentsData, int num, int rate = 44100, bool stereo = true);
} // End of namespace Audio