aboutsummaryrefslogtreecommitdiff
path: root/simon/midi.cpp
diff options
context:
space:
mode:
authorJamieson Christian2002-11-18 09:08:45 +0000
committerJamieson Christian2002-11-18 09:08:45 +0000
commit5214cb3463804bda39b10d52e4a7f6ccd943780d (patch)
treec857f7f0c58bfd65bd5e1e0fb03a0b3c2d434419 /simon/midi.cpp
parent713f11d99eb28474bcb8b31942c89e9fa8b66575 (diff)
downloadscummvm-rg350-5214cb3463804bda39b10d52e4a7f6ccd943780d.tar.gz
scummvm-rg350-5214cb3463804bda39b10d52e4a7f6ccd943780d.tar.bz2
scummvm-rg350-5214cb3463804bda39b10d52e4a7f6ccd943780d.zip
Added support for volume and pause control to Simon music.
Note that MidiStreamer is now used as a streaming wrapper for ALL MidiDriver types, even those that natively support streaming. This is because MidiStreamer supports a hybrid of streamed and non-streamed MIDI, which is necessary to support interactive events. svn-id: r5596
Diffstat (limited to 'simon/midi.cpp')
-rw-r--r--simon/midi.cpp65
1 files changed, 46 insertions, 19 deletions
diff --git a/simon/midi.cpp b/simon/midi.cpp
index 04b727dd77..cf31d24b0f 100644
--- a/simon/midi.cpp
+++ b/simon/midi.cpp
@@ -31,6 +31,13 @@
// FIXME: This is a horrible place to put this, but for now....
#include "sound/midistreamer.cpp"
+MidiPlayer::MidiPlayer() {
+ // Since initialize() is called every time the music changes,
+ // this is where we'll initialize stuff that must persist
+ // between songs.
+ _masterVolume = 255;
+}
+
void MidiPlayer::read_all_songs(File *in, uint music)
{
uint i, num;
@@ -178,21 +185,16 @@ void MidiPlayer::initialize()
int i;
for (i = 0; i != 16; i++)
- _volumeTable[i] = 100;
+ _volumeTable[i] = 127;
_midiDriver->property(MidiDriver::PROP_TIMEDIV, _songs[0].ppqn);
res = _midiDriver->open(MidiDriver::MO_STREAMING);
- if (res == MidiDriver::MERR_STREAMING_NOT_AVAILABLE) {
- // No direct streaming, slap a front-end on.
- _midiDriver = new MidiStreamer (_midiDriver);
- _midiDriver->property (MidiDriver::PROP_TIMEDIV, _songs[0].ppqn);
- _midiDriver->set_stream_callback (this, on_fill);
- res = _midiDriver->open (MidiDriver::MO_STREAMING);
- }
-
if (res != 0)
error("MidiPlayer::initializer, got %s", MidiDriver::get_error_name(res));
+
+ if (_paused)
+ _midiDriver->pause (true);
}
int MidiPlayer::fill(MidiEvent *me, int num_event)
@@ -261,8 +263,8 @@ bool MidiPlayer::fill_helper(NoteRec *nr, MidiEvent *me)
if ((nr->cmd & 0xF0) == 0xB0 && nr->param_1 == 7) {
_volumeTable[nr->cmd & 0xF] = nr->param_2;
- nr->param_1 = 0x76;
- me->event = nr->cmd | (nr->param_1 << 8) | (nr->param_2 << 16) /* | MEVT_F_CALLBACK */ ;
+// nr->param_1 = 0x76;
+ me->event = nr->cmd | (nr->param_1 << 8) | ((nr->param_2 * _masterVolume / 255) << 16) /* | MEVT_F_CALLBACK */ ;
}
return true;
@@ -414,27 +416,52 @@ void MidiPlayer::unload()
void MidiPlayer::play()
{
- _midiDriver->pause(false);
+ if (!_paused)
+ _midiDriver->pause(false);
}
-void MidiPlayer::pause(bool b)
+void MidiPlayer::pause (bool b)
{
+ if (_paused == b)
+ return;
+ _paused = b;
_midiDriver->pause(b);
+
+ for (int i = ARRAYSIZE (_volumeTable); i; --i) {
+ _midiDriver->send (((_paused ? 0 : (_volumeTable[i-1] * _masterVolume / 255)) << 16) | (7 << 8) | 0xB0 | i);
+ }
+
}
-uint MidiPlayer::get_volume()
+int MidiPlayer::get_volume()
{
- // TODO: implement me
- return 0;
+ return _masterVolume;
}
-void MidiPlayer::set_volume(uint volume)
+void MidiPlayer::set_volume (int volume)
{
- // TODO: implement me
+ if (volume < 0)
+ volume = 0;
+ else if (volume > 255)
+ volume = 255;
+
+ if (_masterVolume == volume)
+ return;
+
+ _masterVolume = volume;
+
+ // Now tell all the channels this.
+ if (_midiDriver && !_paused) {
+ for (int i = ARRAYSIZE (_volumeTable); i; --i) {
+ _midiDriver->send (((_volumeTable[i-1] * _masterVolume / 255) << 16) | (7 << 8) | 0xB0 | i);
+ }
+ }
}
void MidiPlayer::set_driver(MidiDriver *md)
{
- _midiDriver = md;
+ // We must always use the MidiStreamer front-end
+ // so we can support user-initiated MIDI events (like volume).
+ _midiDriver = new MidiStreamer (md);
_midiDriver->set_stream_callback(this, on_fill);
}