diff options
author | Jamieson Christian | 2003-10-05 15:36:52 +0000 |
---|---|---|
committer | Jamieson Christian | 2003-10-05 15:36:52 +0000 |
commit | a722d0601e4ae87b15fe09f62b3a1076c6c8646e (patch) | |
tree | 511293906e3b210764b047191d68278e4d8cf138 /scumm | |
parent | 7174a32c8e877627c51da50b657083873aeef1e6 (diff) | |
download | scummvm-rg350-a722d0601e4ae87b15fe09f62b3a1076c6c8646e.tar.gz scummvm-rg350-a722d0601e4ae87b15fe09f62b3a1076c6c8646e.tar.bz2 scummvm-rg350-a722d0601e4ae87b15fe09f62b3a1076c6c8646e.zip |
Preliminary preparation for new YM2612 FM emulator.
All the hooks are in, but actual implementation
needs to be checked for portability.
svn-id: r10615
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/imuse.cpp | 11 | ||||
-rw-r--r-- | scumm/imuse.h | 13 | ||||
-rw-r--r-- | scumm/imuse_internal.h | 12 | ||||
-rw-r--r-- | scumm/imuse_player.cpp | 31 | ||||
-rw-r--r-- | scumm/midiparser_eup.cpp | 47 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 8 |
6 files changed, 88 insertions, 34 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index 223e32ad4f..602627ef4b 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -54,6 +54,7 @@ _initialized(false), _tempoFactor(0), _player_limit(ARRAYSIZE(_players)), _recycle_players(false), +_direct_passthrough(false), _queue_end(0), _queue_pos(0), _queue_sound(0), @@ -250,7 +251,7 @@ bool IMuseInternal::startSound(int sound) { return false; player->clear(); - return player->startSound(sound, driver); + return player->startSound(sound, driver, _direct_passthrough); } @@ -1117,10 +1118,14 @@ uint32 IMuseInternal::property(int prop, uint32 value) { break; case IMuse::PROP_RECYCLE_PLAYERS: - if (value > 0 && value <= ARRAYSIZE(_players)) - _recycle_players = (value != 0); + _recycle_players = (value != 0); + break; + + case IMuse::PROP_DIRECT_PASSTHROUGH: + _direct_passthrough = (value != 0); break; } + return 0; } diff --git a/scumm/imuse.h b/scumm/imuse.h index be19ba0372..acebe40529 100644 --- a/scumm/imuse.h +++ b/scumm/imuse.h @@ -51,12 +51,13 @@ public: ~IMuse(); enum { - PROP_TEMPO_BASE = 1, - PROP_NATIVE_MT32 = 2, - PROP_MULTI_MIDI = 3, - PROP_OLD_ADLIB_INSTRUMENTS = 4, - PROP_LIMIT_PLAYERS = 5, - PROP_RECYCLE_PLAYERS = 6 + PROP_TEMPO_BASE, + PROP_NATIVE_MT32, + PROP_MULTI_MIDI, + PROP_OLD_ADLIB_INSTRUMENTS, + PROP_LIMIT_PLAYERS, + PROP_RECYCLE_PLAYERS, + PROP_DIRECT_PASSTHROUGH }; void on_timer(MidiDriver *midi); diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h index 0265df65d5..e7e91b3f22 100644 --- a/scumm/imuse_internal.h +++ b/scumm/imuse_internal.h @@ -60,10 +60,6 @@ class ScummEngine; #define TICKS_PER_BEAT 480 -#define IMUSE_SYSEX_ID 0x7D -#define ROLAND_SYSEX_ID 0x41 -#define PERCUSSION_CHANNEL 9 - #define TRIGGER_ID 0 #define COMMAND_ID 1 @@ -158,6 +154,7 @@ protected: protected: MidiDriver *_midi; MidiParser *_parser; + bool _passThrough; // Only respond to EOT, all else direct to MidiDriver Part *_parts; bool _active; @@ -259,7 +256,7 @@ public: void setSpeed(byte speed); int setTranspose(byte relative, int b); int setVolume(byte vol); - bool startSound(int sound, MidiDriver *midi); + bool startSound(int sound, MidiDriver *midi, bool passThrough); int getMusicTimer() const; public: @@ -366,8 +363,9 @@ protected: int _tempoFactor; - int _player_limit; // Limits how many simultaneous music tracks are played - bool _recycle_players; // Can we stop a player in order to start another one? + int _player_limit; // Limits how many simultaneous music tracks are played + bool _recycle_players; // Can we stop a player in order to start another one? + bool _direct_passthrough; // Pass data direct to MidiDriver (no interactivity) uint _queue_end, _queue_pos, _queue_sound; byte _queue_adding; diff --git a/scumm/imuse_player.cpp b/scumm/imuse_player.cpp index 69b577ed43..23048341b3 100644 --- a/scumm/imuse_player.cpp +++ b/scumm/imuse_player.cpp @@ -39,6 +39,11 @@ namespace Scumm { // //////////////////////////////////////// +#define IMUSE_SYSEX_ID 0x7D +#define YM2612_SYSEX_ID 0x7C +#define ROLAND_SYSEX_ID 0x41 +#define PERCUSSION_CHANNEL 9 + extern MidiParser *MidiParser_createRO(); extern MidiParser *MidiParser_createEUP(); @@ -85,7 +90,7 @@ Player::~Player() { } } -bool Player::startSound(int sound, MidiDriver *midi) { +bool Player::startSound(int sound, MidiDriver *midi, bool passThrough) { void *ptr; int i; @@ -111,6 +116,7 @@ bool Player::startSound(int sound, MidiDriver *midi) { _pan = 0; _transpose = 0; _detune = 0; + _passThrough = passThrough; for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i) _parameterFaders[i].init(); @@ -152,8 +158,11 @@ void Player::clear() { debug (0, "Stopping music %d", _id); #endif - if (_parser) + if (_parser) { _parser->unloadMusic(); + delete _parser; + _parser = 0; + } uninit_parts(); _se->ImFireAllTriggers(_id); _active = false; @@ -224,6 +233,11 @@ void Player::setSpeed(byte speed) { } void Player::send(uint32 b) { + if (_passThrough) { + _midi->send (b); + return; + } + byte cmd = (byte)(b & 0xF0); byte chan = (byte)(b & 0x0F); byte param1 = (byte)((b >> 8) & 0xFF); @@ -333,8 +347,12 @@ void Player::sysEx(byte *p, uint16 len) { byte buf[128]; Part *part; + if (_passThrough) { + _midi->sysEx (p, len); + return; + } + // Check SysEx manufacturer. - // Roland is 0x41 a = *p++; --len; if (a != IMUSE_SYSEX_ID) { @@ -346,6 +364,9 @@ void Player::sysEx(byte *p, uint16 len) { if (part->clearToTransmit()) part->_instrument.send(part->_mc); } + } else if (a == YM2612_SYSEX_ID) { + // FM-Towns custom instrument definition + _midi->sysEx_customInstrument (p[0], 'EUP ', p + 1); } else { warning("Unknown SysEx manufacturer 0x%02X", (int) a); } @@ -1124,10 +1145,8 @@ uint32 Player::getBaseTempo() { } void Player::metaEvent(byte type, byte *msg, uint16 len) { - if (type == 0x2F) { - _parser->unloadMusic(); + if (type == 0x2F) clear(); - } } diff --git a/scumm/midiparser_eup.cpp b/scumm/midiparser_eup.cpp index a094ade5ce..8ba23c1a96 100644 --- a/scumm/midiparser_eup.cpp +++ b/scumm/midiparser_eup.cpp @@ -32,6 +32,8 @@ namespace Scumm { */ class MidiParser_EUP : public MidiParser { protected: + byte _instruments[6][50]; // Two extra bytes for SysEx ID and channel # + byte _channel_instr[16]; struct { byte *enable; int8 *channel; @@ -69,14 +71,22 @@ void MidiParser_EUP::parseNextEvent (EventInfo &info) { // program changes to get a reasonable "one-size- // fits-all" sound until we actually support the // FM synthesis capabilities of FM Towns. - if (_presend) { - --_presend; + for (; _presend < 32; ++_presend) { + if (_channel_instr[_presend >> 1] == 0xFF) continue; info.start = pos; info.delta = 0; - info.event = ((_presend & 1) ? 0xB0 : 0xC0) | (_presend >> 1); - info.basic.param1 = ((_presend & 1) ? 7 : 0x38); - info.basic.param2 = ((_presend & 1) ? 127 : 0); - _presend = (_presend + 2) % 32; + if (_presend & 1) { + info.event = 0xB0; + info.basic.param1 = 7; + info.basic.param2 = 127; + } else { + byte *data = &_instruments[_channel_instr[_presend >> 1]][0]; + data[1] = _presend >> 1; + info.event = 0xF0; + info.ext.data = data; + info.length = 48; + } + ++_presend; return; } @@ -89,7 +99,17 @@ void MidiParser_EUP::parseNextEvent (EventInfo &info) { channel = cmd & 0x0F; uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _base_tick; int note = (int) pos[4] + _presets.transpose[preset]; - int volume = (int) pos[5] + _presets.volume[preset]; + int volume = (int) pos[5]; + // HACK: Loom-Towns distaff tracks seem to + // contain zero-volume note events, so change + // those to full volume. + if (!volume) + volume = 127; + volume += _presets.volume[preset]; + if (volume > 127) + volume = 127; + else if (volume < 0) + volume = 0; pos += 6; if (_presets.enable[preset]) { uint16 duration = pos[1] | (pos[2] << 4); @@ -148,7 +168,12 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) { } byte numInstruments = pos[16]; - pos += (16 + 2 + numInstruments * 48); + pos += 16 + 2; + for (int i = 0; i < numInstruments; ++i) { + _instruments[i][0] = 0x7C; + memcpy (&_instruments[i][2], pos, 48); + pos += 48; + } // Load the prest pointers _presets.enable = pos; @@ -161,6 +186,10 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) { pos += 32; pos += 8; // Unknown bytes + for (i = 0; i < 16; ++i) + _channel_instr[i] = 0xFF; + for (i = 0; i < 6; ++i) + _channel_instr[pos[i]] = i; pos += 6; // Instrument-to-channel mapping (not supported yet) pos += 4; // Skip the music size for now. pos++; // Unknown byte @@ -183,7 +212,7 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) { void MidiParser_EUP::resetTracking() { MidiParser::resetTracking(); - _presend = 1; + _presend = 0; _base_tick = 0; } diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index fc8dfa16d0..ad421fb38d 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -92,15 +92,15 @@ static const TargetSettings scumm_settings[] = { /* Scumm Version 3 */ {"indy3EGA", "Indiana Jones and the Last Crusade", GID_INDY3, 3, MDT_PCSPK | MDT_ADLIB, GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"}, - {"indy3Towns", "Indiana Jones and the Last Crusade (FM Towns)", GID_INDY3, 3, MDT_ADLIB, + {"indy3Towns", "Indiana Jones and the Last Crusade (FM Towns)", GID_INDY3, 3, MDT_TOWNS, GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"}, {"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3, 3, MDT_PCSPK | MDT_ADLIB, GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, "00.LFL"}, - {"zak256", "Zak McKracken and the Alien Mindbenders (256)", GID_ZAK256, 3, MDT_ADLIB, + {"zak256", "Zak McKracken and the Alien Mindbenders (256)", GID_ZAK256, 3, MDT_TOWNS, GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"}, {"loom", "Loom", GID_LOOM, 3, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE, GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE, "00.LFL"}, - {"loomTowns", "Loom (FM Towns)", GID_LOOM, 3, MDT_ADLIB, + {"loomTowns", "Loom (FM Towns)", GID_LOOM, 3, MDT_TOWNS, GF_SMALL_HEADER | GF_SMALL_NAMES | GF_NO_SCALING | GF_OLD256 | GF_FMTOWNS | GF_AUDIOTRACKS, "00.LFL"}, /* Scumm Version 4 */ @@ -696,6 +696,8 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst) _imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1); _imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1); } + if (_features & GF_FMTOWNS) + _imuse->property(IMuse::PROP_DIRECT_PASSTHROUGH, 1); _imuse->set_music_volume(_sound->_sound_volume_music); } } |