aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/sound/midiparser_sci.cpp23
-rw-r--r--engines/sci/sound/midiparser_sci.h3
-rw-r--r--engines/sci/sound/music.cpp12
-rw-r--r--engines/sci/sound/music.h6
-rw-r--r--engines/sci/sound/soundcmd.cpp15
5 files changed, 47 insertions, 12 deletions
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index bdb907a451..1ea990332b 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -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;
diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h
index 4888fa06ca..89d1e63d8c 100644
--- a/engines/sci/sound/midiparser_sci.h
+++ b/engines/sci/sound/midiparser_sci.h
@@ -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
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index a1c6cc0a56..c5fc07bfd7 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -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);
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index bbafb808cb..8e68d3df92 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -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);
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 6ee23d7fc8..fa215ac302 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -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
}