SCI: implemented channel muting for sci1, finally fixes lsl5 paino scene with patti

svn-id: r49926
This commit is contained in:
Martin Kiewitz 2010-06-17 11:54:54 +00:00
parent 3a8e11767d
commit 423029c027
5 changed files with 47 additions and 12 deletions

View File

@ -79,6 +79,7 @@ bool MidiParser_SCI::loadMusic(SoundResource::Track *track, MusicEntry *psnd, in
for (int i = 0; i < 15; i++) {
_channelUsed[i] = false;
_channelRemap[i] = -1;
_channelMuted[i] = false;
}
_channelRemap[9] = 9; // never map channel 9, because that's used for percussion
_channelRemap[15] = 15; // never map channel 15, because thats used by sierra internally
@ -143,8 +144,22 @@ void MidiParser_SCI::unloadMusic() {
}
void MidiParser_SCI::sendToDriver(uint32 b) {
byte midiChannel = b & 0xf;
if ((b & 0xFFF0) == 0x4EB0) {
// this is channel mute only for sci1
// it's velocity control for sci0
if (_soundVersion >= SCI_VERSION_1_EARLY) {
_channelMuted[midiChannel] = b & 0xFF0000 ? true : false;
return; // don't send this to driver at all
}
}
// Is channel muted? if so, don't send command
if (_channelMuted[midiChannel])
return;
// Channel remapping
int16 realChannel = _channelRemap[b & 0xf];
int16 realChannel = _channelRemap[midiChannel];
assert(realChannel != -1);
b = (b & 0xFFFFFFF0) | realChannel;
_driver->send(b);
@ -249,7 +264,6 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
case 0x0A: // pan
case 0x0B: // expression
case 0x40: // sustain
case 0x4E: // velocity control
case 0x79: // reset all
case 0x7B: // notes off
// These are all handled by the music driver, so ignore them
@ -263,8 +277,11 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
break;
}
}
if (info.basic.param1 == 7) // channel volume change -scale it
switch (info.basic.param1) {
case 7: // channel volume change -scale it
info.basic.param2 = info.basic.param2 * _volume / MUSIC_VOLUME_MAX;
break;
}
info.length = 0;
break;

View File

@ -76,9 +76,9 @@ public:
const byte *getMixedData() const { return _mixedData; }
void tryToOwnChannels();
void sendToDriver(uint32 b);
protected:
void sendToDriver(uint32 b);
void parseNextEvent(EventInfo &info);
byte *midiMixChannels();
byte *midiFilterChannels(int channelMask);
@ -101,6 +101,7 @@ protected:
bool _channelUsed[16];
int16 _channelRemap[16];
bool _channelMuted[16];
};
} // End of namespace Sci

View File

@ -446,6 +446,18 @@ void SciMusic::soundSetMasterVolume(uint16 vol) {
_pMidiDrv->setVolume(vol);
}
void SciMusic::sendMidiCommand(uint32 cmd) {
Common::StackLock lock(_mutex);
_pMidiDrv->send(cmd);
}
void SciMusic::sendMidiCommand(MusicEntry *pSnd, uint32 cmd) {
if (pSnd->pMidiParser)
pSnd->pMidiParser->sendToDriver(cmd);
else
warning("tried to cmdSendMidi on non midi slot (%04x:%04x)", PRINT_REG(pSnd->soundObj));
}
void SciMusic::printPlayList(Console *con) {
Common::StackLock lock(_mutex);

View File

@ -179,10 +179,8 @@ public:
MusicList::iterator getPlayListStart() { return _playList.begin(); }
MusicList::iterator getPlayListEnd() { return _playList.end(); }
void sendMidiCommand(uint32 cmd) {
Common::StackLock lock(_mutex);
_pMidiDrv->send(cmd);
}
void sendMidiCommand(uint32 cmd);
void sendMidiCommand(MusicEntry *pSnd, uint32 cmd);
void setReverb(byte reverb);

View File

@ -232,9 +232,8 @@ reg_t SoundCommandParser::parseCommand(int argc, reg_t *argv, reg_t acc) {
uint16 controller = argv[4].toUint16();
uint16 param = argv[5].toUint16();
if (!channel)
error("invalid channel specified on cmdSendMidi");
channel--; // channel is given 1-based, we are using 0-based
if (channel)
channel--; // channel is given 1-based, we are using 0-based
_midiCommand = (channel | midiCmd) | ((uint32)controller << 8) | ((uint32)param << 16);
}
@ -901,7 +900,15 @@ void SoundCommandParser::cmdSendMidi(reg_t obj, int16 value) {
//SongHandle handle = FROBNICATE_HANDLE(obj);
//_state->sfx_send_midi(handle, value, _midiCmd, _controller, _param);
#else
_music->sendMidiCommand(_midiCommand);
MusicEntry *musicSlot = _music->getSlot(obj);
if (!musicSlot) {
// TODO: maybe it's possible to call this with obj == 0:0 and send directly?!
// if so, allow it
//_music->sendMidiCommand(_midiCommand);
warning("cmdSendMidi: Slot not found (%04x:%04x)", PRINT_REG(obj));
return;
}
_music->sendMidiCommand(musicSlot, _midiCommand);
#endif
}