aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
Diffstat (limited to 'scumm')
-rw-r--r--scumm/imuse.cpp82
-rw-r--r--scumm/imuse_internal.h44
-rw-r--r--scumm/imuse_player.cpp128
3 files changed, 92 insertions, 162 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index 8591463891..9509151f19 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -66,7 +66,6 @@ _snm_trigger_index(0)
memset(_channel_volume,0,sizeof(_channel_volume));
memset(_channel_volume_eff,0,sizeof(_channel_volume_eff));
memset(_volchan_table,0,sizeof(_volchan_table));
- memset(_active_notes,0,sizeof(_active_notes));
}
byte *IMuseInternal::findStartOfSound(int sound) {
@@ -865,7 +864,7 @@ int32 IMuseInternal::doCommand (int numargs, int a[]) {
case 21:
return -1;
case 22:
- ((Part *)player)->setVolume(a[3]);
+ ((Part *)player)->volume(a[3]);
return 0;
case 23:
return query_queue(a[1]);
@@ -1425,7 +1424,7 @@ void Part::set_detune(int8 detune) {
}
}
-void Part::set_pitchbend(int value) {
+void Part::pitchBend(int16 value) {
_pitchbend = value;
if (_mc) {
_mc->pitchBend(clamp(_pitchbend +
@@ -1434,8 +1433,8 @@ void Part::set_pitchbend(int value) {
}
}
-void Part::setVolume(uint8 vol) {
- _vol_eff = ((_vol = vol) + 1) * _player->getEffectiveVolume() >> 7;
+void Part::volume (byte value) {
+ _vol_eff = ((_vol = value) + 1) * _player->getEffectiveVolume() >> 7;
if (_mc)
_mc->volume(_vol_eff);
}
@@ -1461,47 +1460,47 @@ void Part::set_transpose(int8 transpose) {
}
}
-void Part::set_pedal(bool value) {
+void Part::sustain(bool value) {
_pedal = value;
if (_mc)
- _mc->sustain(_pedal);
+ _mc->sustain(value);
}
-void Part::set_modwheel(uint value) {
+void Part::modulationWheel(byte value) {
_modwheel = value;
if (_mc)
- _mc->modulationWheel(_modwheel);
+ _mc->modulationWheel(value);
}
-void Part::set_chorus(uint chorus) {
- _chorus = chorus;
+void Part::chorusLevel(byte value) {
+ _chorus = value;
if (_mc)
- _mc->chorusLevel(_effect_level);
+ _mc->chorusLevel(value);
}
-void Part::set_effect_level(uint level)
+void Part::effectLevel(byte value)
{
- _effect_level = level;
+ _effect_level = value;
if (_mc)
- _mc->effectLevel(_effect_level);
+ _mc->effectLevel(value);
}
void Part::fix_after_load() {
set_transpose(_transpose);
- setVolume(_vol);
+ volume(_vol);
set_detune(_detune);
set_pri(_pri);
set_pan(_pan);
sendAll();
}
-void Part::set_pitchbend_factor(uint8 value) {
+void Part::pitchBendFactor(byte value) {
if (value > 12)
return;
- set_pitchbend(0);
+ pitchBend(0);
_pitchbend_factor = value;
if (_mc)
- _mc->pitchBendFactor(_pitchbend_factor);
+ _mc->pitchBendFactor(value);
}
void Part::set_onoff(bool on) {
@@ -1526,9 +1525,11 @@ void Part::load_global_instrument(byte slot) {
_instrument.send(_mc);
}
-void Part::key_on(byte note, byte velocity) {
+void Part::noteOn(byte note, byte velocity) {
+ if (!_on)
+ return;
+
MidiChannel *mc = _mc;
- _actives[note >> 4] |= (1 <<(note & 0xF));
// DEBUG
if (_unassigned_instrument && !_percussion) {
@@ -1551,9 +1552,11 @@ void Part::key_on(byte note, byte velocity) {
}
}
-void Part::key_off(byte note) {
+void Part::noteOff(byte note) {
+ if (!_on)
+ return;
+
MidiChannel *mc = _mc;
- _actives[note >> 4] &= ~(1 <<(note & 0xF));
if (mc) {
mc->noteOff(note);
} else if (_percussion) {
@@ -1568,7 +1571,6 @@ void Part::init() {
_next = NULL;
_prev = NULL;
_mc = NULL;
- memset(_actives, 0, sizeof(_actives));
}
void Part::setup(Player *player) {
@@ -1611,7 +1613,6 @@ void Part::off() {
_mc->release();
_mc = NULL;
}
- memset(_actives, 0, sizeof(_actives));
}
bool Part::clearToTransmit() {
@@ -1637,33 +1638,9 @@ void Part::sendAll() {
_mc->priority(_pri_eff);
}
-int Part::update_actives(uint16 *active) {
- int i, j;
- uint16 *act, mask, bits;
- int count = 0;
-
- bits = 1 << _chan;
- act = _actives;
-
- for (i = 8; i; i--) {
- mask = *act++;
- if (mask) {
- for (j = 16; j; j--, mask >>= 1, active++) {
- if (mask & 1 && !(*active & bits)) {
- *active |= bits;
- count++;
- }
- }
- } else {
- active += 16;
- }
- }
- return count;
-}
-
-void Part::set_program(byte program) {
+void Part::programChange(byte value) {
_bank = 0;
- _instrument.program(program, _player->isMT32());
+ _instrument.program(value, _player->isMT32());
if (clearToTransmit())
_instrument.send(_mc);
}
@@ -1677,11 +1654,10 @@ void Part::set_instrument(uint b) {
_instrument.send(_mc);
}
-void Part::silence() {
+void Part::allNotesOff() {
if (!_mc)
return;
_mc->allNotesOff();
- memset(_actives, 0, sizeof(_actives));
}
////////////////////////////////////////
diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h
index 4d74679336..03426a0538 100644
--- a/scumm/imuse_internal.h
+++ b/scumm/imuse_internal.h
@@ -148,6 +148,11 @@ struct CommandQueue {
class Player : public MidiDriver {
protected:
+ // Moved from IMuseInternal.
+ // This is only used by one player at a time.
+ static uint16 _active_notes[128];
+
+protected:
MidiDriver *_midi;
MidiParser *_parser;
@@ -188,8 +193,6 @@ protected:
void hook_clear();
void uninit_parts();
byte *parse_midi(byte *s);
- void key_off(uint8 chan, byte data);
- void key_on(uint8 chan, byte data, byte velocity);
void part_set_transpose(uint8 chan, byte relative, int8 b);
void parse_sysex(byte *p, uint len);
void maybe_jump(byte cmd, uint track, uint beat, uint tick);
@@ -198,7 +201,6 @@ protected:
void maybe_set_volume(byte *data);
void maybe_set_program(byte *data);
void maybe_set_transpose_part(byte *data);
- uint update_actives();
void turn_off_pedals();
int query_part_param(int param, byte chan);
void turn_off_parts();
@@ -208,10 +210,6 @@ protected:
static void decode_sysex_bytes(const byte *src, byte *dst, int len);
- void clear_active_note(int chan, byte note);
- void set_active_note(int chan, byte note);
- void clear_active_notes();
-
// Sequencer part
int start_seq_sound(int sound, bool reset_vars = true);
int query_param(int param);
@@ -301,36 +299,35 @@ struct Part {
Instrument _instrument;
bool _unassigned_instrument; // For diagnostic reporting purposes only
- // Used to be in MidiDriver
- uint16 _actives[8];
+ // MidiChannel interface
+ // (We don't currently derive from MidiChannel,
+ // but if we ever do, this will make it easy.)
+ void noteOff(byte note);
+ void noteOn(byte note, byte velocity);
+ void programChange(byte value);
+ void pitchBend(int16 value);
+ void modulationWheel(byte value);
+ void volume(byte value);
+ void pitchBendFactor(byte value);
+ void sustain(bool value);
+ void effectLevel(byte value);
+ void chorusLevel(byte value);
+ void allNotesOff();
- void key_on(byte note, byte velocity);
- void key_off(byte note);
void set_param(byte param, int value) { }
void init();
void setup(Player *player);
void uninit();
void off();
- void silence();
void set_instrument(uint b);
void set_instrument(byte *data);
void load_global_instrument(byte b);
void set_transpose(int8 transpose);
- void setVolume(uint8 volume);
void set_detune(int8 detune);
void set_pri(int8 pri);
void set_pan(int8 pan);
- void set_modwheel(uint value);
- void set_pedal(bool value);
- void set_pitchbend(int value);
- void release_pedal();
- void set_program(byte program);
- void set_chorus(uint chorus);
- void set_effect_level(uint level);
-
- int update_actives(uint16 *active);
- void set_pitchbend_factor(uint8 value);
+
void set_onoff(bool on);
void fix_after_load();
@@ -386,7 +383,6 @@ protected:
Player _players[8];
Part _parts[32];
- uint16 _active_notes[128];
Instrument _global_adlib_instruments[32];
CommandQueue _cmd_queue[64];
DeferredCommand _deferredCommands[4];
diff --git a/scumm/imuse_player.cpp b/scumm/imuse_player.cpp
index d3bb913f0f..cb15e56151 100644
--- a/scumm/imuse_player.cpp
+++ b/scumm/imuse_player.cpp
@@ -34,16 +34,14 @@
////////////////////////////////////////
//
-// Helper functions
+// Miscellaneous
//
////////////////////////////////////////
extern MidiParser *MidiParser_createRO();
extern MidiParser *MidiParser_createEUP();
-static uint read_word(byte *a) {
- return (a[0] << 8) + a[1];
-}
+uint16 Player::_active_notes[128];
@@ -233,17 +231,21 @@ void Player::send(uint32 b) {
switch (cmd >> 4) {
case 0x8: // Key Off
- if (!_scanning)
- key_off(chan, param1);
- else
- clear_active_note(chan, param1);
+ if (!_scanning) {
+ if ((part = getPart(chan)) != 0)
+ part->noteOff(param1);
+ } else {
+ _active_notes[param1] &= ~(1 << chan);
+ }
break;
case 0x9: // Key On
- if (!_scanning)
- key_on(chan, param1, param2);
- else
- set_active_note(chan, param1);
+ if (!_scanning) {
+ if ((part = getPart(chan)) != 0)
+ part->noteOn(param1, param2);
+ } else {
+ _active_notes[param1] |= (1 << chan);
+ }
break;
case 0xB: // Control Change
@@ -253,16 +255,16 @@ void Player::send(uint32 b) {
switch (param1) {
case 1: // Modulation Wheel
- part->set_modwheel(param2);
+ part->modulationWheel(param2);
break;
case 7: // Volume
- part->setVolume(param2);
+ part->volume(param2);
break;
case 10: // Pan Position
part->set_pan(param2 - 0x40);
break;
case 16: // Pitchbend Factor(non-standard)
- part->set_pitchbend_factor(param2);
+ part->pitchBendFactor(param2);
break;
case 17: // GP Slider 2
part->set_detune(param2 - 0x40);
@@ -272,16 +274,16 @@ void Player::send(uint32 b) {
_se->reallocateMidiChannels(_midi);
break;
case 64: // Sustain Pedal
- part->set_pedal(param2 != 0);
+ part->sustain(param2 != 0);
break;
case 91: // Effects Level
- part->set_effect_level(param2);
+ part->effectLevel(param2);
break;
case 93: // Chorus Level
- part->set_chorus(param2);
+ part->chorusLevel(param2);
break;
case 123: // All Notes Off
- part->silence();
+ part->allNotesOff();
break;
default:
warning("Player::send(): Invalid control change %d", param1);
@@ -293,7 +295,7 @@ void Player::send(uint32 b) {
if (part) {
if (_isGM) {
if (param1 < 128)
- part->set_program(param1);
+ part->programChange(param1);
} else {
if (param1 < 32)
part->load_global_instrument(param1);
@@ -304,7 +306,7 @@ void Player::send(uint32 b) {
case 0xE: // Pitch Bend
part = getPart(chan);
if (part)
- part->set_pitchbend(((param2 << 7) | param1) - 0x2000);
+ part->pitchBend(((param2 << 7) | param1) - 0x2000);
break;
case 0xA: // Aftertouch
@@ -384,7 +386,7 @@ void Player::sysEx(byte *p, uint16 len) {
if (part) {
part->set_onoff(p[2] & 0x01);
part->set_pri (p[4]);
- part->setVolume((p[5] & 0x0F) << 4 |(p[6] & 0x0F));
+ part->volume((p[5] & 0x0F) << 4 |(p[6] & 0x0F));
part->_percussion = _isGM ?((p[9] & 0x08) > 0) : false;
if (part->_percussion) {
if (part->_mc) {
@@ -424,7 +426,7 @@ void Player::sysEx(byte *p, uint16 len) {
// This SysEx is used in Sam & Max for maybe_jump.
if (_scanning)
break;
- maybe_jump(p[0], p[1] - 1, (read_word(p + 2) - 1) * 4 + p[4], ((p[5] * TICKS_PER_BEAT) >> 2) + p[6]);
+ maybe_jump(p[0], p[1] - 1, (READ_BE_UINT16(p + 2) - 1) * 4 + p[4], ((p[5] * TICKS_PER_BEAT) >> 2) + p[6]);
break;
case 2: // Start of song. Ignore for now.
@@ -440,7 +442,7 @@ void Player::sysEx(byte *p, uint16 len) {
part->set_instrument((byte *) buf);
} else {
// SPK tracks have len == 49 here, and are not supported
- part->set_program(254); // Must be invalid, but not 255(which is reserved)
+ part->programChange(254); // Must be invalid, but not 255(which is reserved)
}
}
break;
@@ -458,14 +460,14 @@ void Player::sysEx(byte *p, uint16 len) {
decode_sysex_bytes(p, buf, len - 3);
part = getPart(a);
if (part)
- part->set_param(read_word(buf), read_word(buf + 2));
+ part->set_param(READ_BE_UINT16(buf), READ_BE_UINT16(buf + 2));
break;
case 48: // Hook - jump
if (_scanning)
break;
decode_sysex_bytes(p + 1, buf, len - 2);
- maybe_jump(buf[0], read_word(buf + 1), read_word(buf + 3), read_word(buf + 5));
+ maybe_jump(buf[0], READ_BE_UINT16(buf + 1), READ_BE_UINT16(buf + 3), READ_BE_UINT16(buf + 5));
break;
case 49: // Hook - global transpose
@@ -507,9 +509,9 @@ void Player::sysEx(byte *p, uint16 len) {
case 80: // Loop
decode_sysex_bytes(p + 1, buf, len - 2);
- setLoop(read_word(buf),
- read_word(buf + 2), read_word(buf + 4), read_word(buf + 6), read_word(buf + 8)
- );
+ setLoop(READ_BE_UINT16(buf), READ_BE_UINT16(buf + 2),
+ READ_BE_UINT16(buf + 4), READ_BE_UINT16(buf + 6),
+ READ_BE_UINT16(buf + 8));
break;
case 81: // End loop
@@ -609,7 +611,7 @@ void Player::maybe_set_volume(byte *data) {
part = getPart(chan);
if (part)
- part->setVolume(data[2]);
+ part->volume(data[2]);
}
void Player::maybe_set_program(byte *data) {
@@ -632,7 +634,7 @@ void Player::maybe_set_program(byte *data) {
part = getPart(chan);
if (part)
- part->set_program(data[2]);
+ part->programChange(data[2]);
}
void Player::maybe_set_transpose_part(byte *data) {
@@ -673,18 +675,6 @@ int Player::setTranspose(byte relative, int b) {
return 0;
}
-void Player::clear_active_notes() {
- memset(_se->_active_notes, 0, sizeof(_se->_active_notes));
-}
-
-void Player::clear_active_note(int chan, byte note) {
- _se->_active_notes[note] &= ~(1 << chan);
-}
-
-void Player::set_active_note(int chan, byte note) {
- _se->_active_notes[note] |= (1 << chan);
-}
-
void Player::part_set_transpose(uint8 chan, byte relative, int8 b) {
Part *part;
@@ -699,25 +689,6 @@ void Player::part_set_transpose(uint8 chan, byte relative, int8 b) {
part->set_transpose(b);
}
-void Player::key_on(uint8 chan, byte note, uint8 velocity) {
- Part *part;
-
- part = getPart(chan);
- if (!part || !part->_on)
- return;
-
- part->key_on(note, velocity);
-}
-
-void Player::key_off(uint8 chan, byte note) {
- Part *part;
-
- for (part = _parts; part; part = part->_next) {
- if (part->_chan == (byte)chan && part->_on)
- part->key_off(note);
- }
-}
-
bool Player::jump(uint track, uint beat, uint tick) {
if (!_parser)
return false;
@@ -755,7 +726,7 @@ void Player::turn_off_pedals() {
for (part = _parts; part; part = part->_next) {
if (part->_pedal)
- part->set_pedal(false);
+ part->sustain(false);
}
}
@@ -794,20 +765,6 @@ Part *Player::getPart(uint8 chan) {
return part;
}
-uint Player::update_actives() {
- Part *part;
- uint16 *active;
- int count = 0;
-
- clear_active_notes();
- active = _se->_active_notes;
- for (part = _parts; part; part = part->_next) {
- if (part->_mc)
- count += part->update_actives(active);
- }
- return count;
-}
-
void Player::setPriority(int pri) {
Part *part;
@@ -844,7 +801,7 @@ int Player::scan(uint totrack, uint tobeat, uint totick) {
tobeat++;
turn_off_parts();
- clear_active_notes();
+ memset(_active_notes, 0, sizeof(_active_notes));
_scanning = true;
// If the scan involves a track switch, scan to the end of
@@ -880,13 +837,14 @@ void Player::turn_off_parts() {
void Player::play_active_notes() {
int i, j;
uint mask;
+ Part *part;
- for (i = 0; i != 128; i++) {
- mask = _se->_active_notes[i];
- for (j = 0; j != 16; j++, mask >>= 1) {
- if (mask & 1) {
- key_on(j, i, 80);
- }
+ for (i = 0; i < 16; ++i) {
+ part = getPart (i);
+ mask = 1 << i;
+ for (j = 0; j < 128; ++j) {
+ if (_active_notes[j] & mask)
+ part->noteOn (j, 80);
}
}
}
@@ -901,7 +859,7 @@ int Player::setVolume(byte vol) {
_vol_eff = _se->get_channel_volume(_vol_chan) *(vol + 1) >> 7;
for (part = _parts; part; part = part->_next) {
- part->setVolume(part->_vol);
+ part->volume(part->_vol);
}
return 0;