[Scummvm-cvs-logs] SF.net SVN: scummvm:[40874] scummvm/trunk/engines/sci/sfx
waltervn at users.sourceforge.net
waltervn at users.sourceforge.net
Mon May 25 00:32:21 CEST 2009
Revision: 40874
http://scummvm.svn.sourceforge.net/scummvm/?rev=40874&view=rev
Author: waltervn
Date: 2009-05-24 22:32:21 +0000 (Sun, 24 May 2009)
Log Message:
-----------
SCI: Adlib: added support for rhythm channel
Modified Paths:
--------------
scummvm/trunk/engines/sci/sfx/iterator.cpp
scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp
scummvm/trunk/engines/sci/sfx/softseq/adlib.h
Modified: scummvm/trunk/engines/sci/sfx/iterator.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/iterator.cpp 2009-05-24 22:10:12 UTC (rev 40873)
+++ scummvm/trunk/engines/sci/sfx/iterator.cpp 2009-05-24 22:32:21 UTC (rev 40874)
@@ -131,12 +131,18 @@
tell_synth_func *tell = sfx_get_player_tell_func();
for (int i = 0; i < MIDI_CHANNELS; i++) {
- if (saw_notes & (1 << i)) {
+ if (playmask & (1 << i)) {
buf[0] = 0xe0 | i; /* Pitch bend */
buf[1] = 0x80; /* Wheel center */
buf[2] = 0x40;
if (tell)
tell(3, buf);
+
+ buf[0] = 0xb0 | i; // Set control
+ buf[1] = 0x40; // Hold pedal
+ buf[2] = 0x00; // Off
+ if (tell)
+ tell(3, buf);
/* TODO: Reset other controls? */
}
}
Modified: scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp 2009-05-24 22:10:12 UTC (rev 40873)
+++ scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp 2009-05-24 22:32:21 UTC (rev 40874)
@@ -111,6 +111,9 @@
_mixer->stopHandle(_mixerSoundHandle);
delete _opl;
+
+ if (_rhythmKeyMap)
+ delete[] _rhythmKeyMap;
}
void MidiDriver_Adlib::setVolume(byte volume) {
@@ -124,10 +127,6 @@
byte op1 = (b >> 8) & 0xff;
byte op2 = (b >> 16) & 0xff;
- // FIXME: Remove this hack after adding support for the rhythm channel
- if (channel == 9)
- return;
-
switch (command) {
case 0x80:
noteOff(channel, op1);
@@ -201,14 +200,12 @@
}
}
-void MidiDriver_Adlib::sysEx(const byte *msg, uint16 length) {
+void MidiDriver_Adlib::loadInstrument(const byte *ins) {
AdlibPatch patch;
- assert(length == 28);
-
// Set data for the operators
for (int i = 0; i < 2; i++) {
- const byte *op = msg + i * 13;
+ const byte *op = ins + i * 13;
patch.op[i].kbScaleLevel = op[0] & 0x3;
patch.op[i].frequencyMult = op[1] & 0xf;
patch.op[i].attackRate = op[3] & 0xf;
@@ -221,12 +218,12 @@
patch.op[i].vibrato = op[10];
patch.op[i].kbScaleRate = op[11];
}
- patch.op[0].waveForm = msg[26] & 0x3;
- patch.op[1].waveForm = msg[27] & 0x3;
+ patch.op[0].waveForm = ins[26] & 0x3;
+ patch.op[1].waveForm = ins[27] & 0x3;
// Set data for the modulator
- patch.mod.feedback = msg[2] & 0x7;
- patch.mod.algorithm = !msg[12]; // Flag is inverted
+ patch.mod.feedback = ins[2] & 0x7;
+ patch.mod.algorithm = !ins[12]; // Flag is inverted
_patches.push_back(patch);
}
@@ -442,10 +439,16 @@
void MidiDriver_Adlib::voiceOn(int voice, int note, int velocity) {
int channel = _voices[voice].channel;
- int patch = _channels[channel].patch;
+ int patch;
_voices[voice].age = 0;
+ if (channel == 9) {
+ patch = CLIP(note, 27, 88) + 101;
+ } else {
+ patch = _channels[channel].patch;
+ }
+
// Set patch if different from current patch
if ((patch != _voices[voice].patch) && _playSwitch) {
_voices[voice].patch = patch;
@@ -464,10 +467,15 @@
}
void MidiDriver_Adlib::setNote(int voice, int note, bool key) {
+ int channel = _voices[voice].channel;
int n, fre, oct;
float delta;
- int bend = _channels[_voices[voice].channel].pitchWheel;
+ int bend = _channels[channel].pitchWheel;
+ if ((channel == 9) && _rhythmKeyMap) {
+ note = _rhythmKeyMap[CLIP(note, 27, 88) - 27];
+ }
+
_voices[voice].note = note;
delta = 0;
@@ -557,6 +565,11 @@
}
void MidiDriver_Adlib::setPatch(int voice, int patch) {
+ if ((patch < 0) || ((uint)patch >= _patches.size())) {
+ warning("ADLIB: Invalid patch %i requested", patch);
+ return;
+ }
+
AdlibModulator &mod = _patches[patch].mod;
// Set the common settings for both operators
@@ -596,6 +609,21 @@
renewNotes(-1, play);
}
+void MidiDriver_Adlib::loadResource(Resource *res) {
+ for (int i = 0; i < 48; i++)
+ loadInstrument(res->data + (28 * i));
+
+ if (res->size == 2690) {
+ for (int i = 48; i < 96; i++)
+ loadInstrument(res->data + 2 + (28 * i));
+ } else if (res->size == 5382) {
+ for (int i = 48; i < 190; i++)
+ loadInstrument(res->data + (28 * i));
+ _rhythmKeyMap = new byte[kRhythmKeys];
+ memcpy(_rhythmKeyMap, res->data + 5320, kRhythmKeys);
+ }
+}
+
int MidiPlayer_Adlib::open(ResourceManager *resmgr) {
assert(resmgr != NULL);
@@ -612,17 +640,8 @@
return -1;
}
- for (int i = 0; i < 48; i++)
- _driver->sysEx(res->data + (28 * i), 28);
+ static_cast<MidiDriver_Adlib *>(_driver)->loadResource(res);
- if (res->size == 2690) {
- for (int i = 48; i < 96; i++)
- _driver->sysEx(res->data + 2 + (28 * i), 28);
- } else if (res->size == 5382) {
- for (int i = 48; i < 190; i++)
- _driver->sysEx(res->data + (28 * i), 28);
- }
-
return static_cast<MidiDriver_Adlib *>(_driver)->open(resmgr->_sciVersion == SCI_VERSION_0);
}
Modified: scummvm/trunk/engines/sci/sfx/softseq/adlib.h
===================================================================
--- scummvm/trunk/engines/sci/sfx/softseq/adlib.h 2009-05-24 22:10:12 UTC (rev 40873)
+++ scummvm/trunk/engines/sci/sfx/softseq/adlib.h 2009-05-24 22:32:21 UTC (rev 40874)
@@ -31,10 +31,11 @@
class MidiDriver_Adlib : public MidiDriver_Emulated {
public:
enum {
- kVoices = 9
+ kVoices = 9,
+ kRhythmKeys = 62
};
- MidiDriver_Adlib(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15) { }
+ MidiDriver_Adlib(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15), _rhythmKeyMap(0) { }
~MidiDriver_Adlib() { }
// MidiDriver
@@ -53,6 +54,7 @@
void setVolume(byte volume);
void playSwitch(bool play);
+ void loadResource(Resource *res);
private:
enum ChannelID {
@@ -102,7 +104,7 @@
struct AdlibVoice {
int8 channel; // MIDI channel that this voice is assigned to or -1
int8 note; // Currently playing MIDI note or -1
- int8 patch; // Currently playing patch or -1
+ int patch; // Currently playing patch or -1
uint8 velocity; // Note velocity
bool isSustained; // Flag indicating a note that is being sustained by the hold pedal
uint16 age; // Age of the current note
@@ -117,10 +119,10 @@
int _masterVolume;
Channel _channels[MIDI_CHANNELS];
AdlibVoice _voices[kVoices];
+ byte *_rhythmKeyMap;
Common::Array<AdlibPatch> _patches;
- void sysEx(const byte *msg, uint16 length);
- AdlibPatch *loadPatch(byte *data);
+ void loadInstrument(const byte *ins);
void voiceOn(int voice, int note, int velocity);
void voiceOff(int voice);
void setPatch(int voice, int patch);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list