diff options
62 files changed, 693 insertions, 686 deletions
diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index c38537248c..a82fffdf0d 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -269,7 +269,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; #define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) @@ -315,21 +315,12 @@ MusicDevices AlsaMusicPlugin::getDevices() const { return devices; } -Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_ALSA(); return Common::kNoError; } -MidiDriver *MidiDriver_ALSA_create() { - MidiDriver *mididriver; - - AlsaMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(ALSA) //REGISTER_PLUGIN_DYNAMIC(ALSA, PLUGIN_TYPE_MUSIC, AlsaMusicPlugin); //#else diff --git a/backends/midi/camd.cpp b/backends/midi/camd.cpp index e4ca3569f2..3486532549 100644 --- a/backends/midi/camd.cpp +++ b/backends/midi/camd.cpp @@ -177,7 +177,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices CamdMusicPlugin::getDevices() const { @@ -188,21 +188,12 @@ MusicDevices CamdMusicPlugin::getDevices() const { return devices; } -Common::Error CamdMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error CamdMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_CAMD(); return Common::kNoError; } -MidiDriver *MidiDriver_CAMD_create() { - MidiDriver *mididriver; - - CamdMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(CAMD) //REGISTER_PLUGIN_DYNAMIC(CAMD, PLUGIN_TYPE_MUSIC, CamdMusicPlugin); //#else diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp index d52547c997..aa0ad75f0a 100644 --- a/backends/midi/coreaudio.cpp +++ b/backends/midi/coreaudio.cpp @@ -218,7 +218,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices CoreAudioMusicPlugin::getDevices() const { @@ -229,21 +229,12 @@ MusicDevices CoreAudioMusicPlugin::getDevices() const { return devices; } -Common::Error CoreAudioMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error CoreAudioMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_CORE(); return Common::kNoError; } -MidiDriver *MidiDriver_CORE_create() { - MidiDriver *mididriver; - - CoreAudioMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(COREAUDIO) //REGISTER_PLUGIN_DYNAMIC(COREAUDIO, PLUGIN_TYPE_MUSIC, CoreAudioMusicPlugin); //#else diff --git a/backends/midi/coremidi.cpp b/backends/midi/coremidi.cpp index e48b98a807..08f36a8b0f 100644 --- a/backends/midi/coremidi.cpp +++ b/backends/midi/coremidi.cpp @@ -190,7 +190,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices CoreMIDIMusicPlugin::getDevices() const { @@ -201,21 +201,12 @@ MusicDevices CoreMIDIMusicPlugin::getDevices() const { return devices; } -Common::Error CoreMIDIMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error CoreMIDIMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_CoreMIDI(); return Common::kNoError; } -MidiDriver *MidiDriver_CoreMIDI_create() { - MidiDriver *mididriver; - - CoreMIDIMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(COREMIDI) //REGISTER_PLUGIN_DYNAMIC(COREMIDI, PLUGIN_TYPE_MUSIC, CoreMIDIMusicPlugin); //#else diff --git a/backends/midi/dmedia.cpp b/backends/midi/dmedia.cpp index 1ec79d8513..8c006b2cd9 100644 --- a/backends/midi/dmedia.cpp +++ b/backends/midi/dmedia.cpp @@ -199,7 +199,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices DMediaMusicPlugin::getDevices() const { @@ -224,21 +224,12 @@ MusicDevices DMediaMusicPlugin::getDevices() const { return devices; } -Common::Error DMediaMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error DMediaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_DMEDIA(); return Common::kNoError; } -MidiDriver *MidiDriver_DMEDIA_create() { - MidiDriver *mididriver; - - DMediaMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(DMEDIA) //REGISTER_PLUGIN_DYNAMIC(DMEDIA, PLUGIN_TYPE_MUSIC, DMediaMusicPlugin); //#else diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp index 55c8239562..216c5802b7 100644 --- a/backends/midi/seq.cpp +++ b/backends/midi/seq.cpp @@ -184,7 +184,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices SeqMusicPlugin::getDevices() const { @@ -195,21 +195,12 @@ MusicDevices SeqMusicPlugin::getDevices() const { return devices; } -Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_SEQ(); return Common::kNoError; } -MidiDriver *MidiDriver_SEQ_create() { - MidiDriver *mididriver; - - SeqMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(SEQ) //REGISTER_PLUGIN_DYNAMIC(SEQ, PLUGIN_TYPE_MUSIC, SeqMusicPlugin); //#else diff --git a/backends/midi/stmidi.cpp b/backends/midi/stmidi.cpp index f99f8f74dd..b00188dfea 100644 --- a/backends/midi/stmidi.cpp +++ b/backends/midi/stmidi.cpp @@ -127,8 +127,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) - const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices StMidiMusicPlugin::getDevices() const { @@ -139,21 +138,12 @@ MusicDevices StMidiMusicPlugin::getDevices() const { return devices; } -Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_STMIDI(); return Common::kNoError; } -MidiDriver *MidiDriver_STMIDI_create() { - MidiDriver *mididriver; - - StMidiMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(STMIDI) //REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); //#else diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp index 1a44e62b16..f507f1e00a 100644 --- a/backends/midi/timidity.cpp +++ b/backends/midi/timidity.cpp @@ -530,7 +530,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices TimidityMusicPlugin::getDevices() const { @@ -539,21 +539,12 @@ MusicDevices TimidityMusicPlugin::getDevices() const { return devices; } -Common::Error TimidityMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error TimidityMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_TIMIDITY(); return Common::kNoError; } -MidiDriver *MidiDriver_TIMIDITY_create() { - MidiDriver *mididriver; - - TimidityMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(TIMIDITY) //REGISTER_PLUGIN_DYNAMIC(TIMIDITY, PLUGIN_TYPE_MUSIC, TimidityMusicPlugin); //#else diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp index 036029644e..d030d9827d 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -30,6 +30,7 @@ #include "sound/musicplugin.h" #include "sound/mpu401.h" +#include "common/config-manager.h" #include <mmsystem.h> @@ -46,11 +47,12 @@ private: HANDLE _streamEvent; HMIDIOUT _mo; bool _isOpen; + int _device; void check_error(MMRESULT result); public: - MidiDriver_WIN() : _isOpen(false) { } + MidiDriver_WIN(int deviceIndex) : _isOpen(false), _device(deviceIndex) { } int open(); void close(); void send(uint32 b); @@ -62,7 +64,7 @@ int MidiDriver_WIN::open() { return MERR_ALREADY_OPEN; _streamEvent = CreateEvent(NULL, true, true, NULL); - MMRESULT res = midiOutOpen((HMIDIOUT *)&_mo, MIDI_MAPPER, (DWORD_PTR)_streamEvent, 0, CALLBACK_EVENT); + MMRESULT res = midiOutOpen((HMIDIOUT *)&_mo, _device, (DWORD_PTR)_streamEvent, 0, CALLBACK_EVENT); if (res != MMSYSERR_NOERROR) { check_error(res); CloseHandle(_streamEvent); @@ -158,32 +160,43 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices WindowsMusicPlugin::getDevices() const { MusicDevices devices; - // TODO: Return a different music type depending on the configuration - // TODO: List the available devices - devices.push_back(MusicDevice(this, "", MT_GM)); + int numDevs = midiOutGetNumDevs(); + MIDIOUTCAPS tmp; + + for (int i = 0; i < numDevs; i++) { + if (midiOutGetDevCaps(i, &tmp, sizeof(MIDIOUTCAPS)) != MMSYSERR_NOERROR) + break; + // There is no way to detect the "MusicType" so I just set it to MT_GM + // The user will have to manually select his MT32 type device and his GM type device. + devices.push_back(MusicDevice(this, tmp.szPname, MT_GM)); + } return devices; } -Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver) const { - *mididriver = new MidiDriver_WIN(); +Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle dev) const { + int devIndex = 0; + bool found = false; + + if (dev) { + MusicDevices i = getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (d->getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) { + found = true; + break; + } + devIndex++; + } + } + *mididriver = new MidiDriver_WIN(found ? devIndex : 0); return Common::kNoError; } -MidiDriver *MidiDriver_WIN_create() { - MidiDriver *mididriver; - - WindowsMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(WINDOWS) //REGISTER_PLUGIN_DYNAMIC(WINDOWS, PLUGIN_TYPE_MUSIC, WindowsMusicPlugin); //#else diff --git a/backends/midi/ypa1.cpp b/backends/midi/ypa1.cpp index fe65d02c10..fb114d625c 100644 --- a/backends/midi/ypa1.cpp +++ b/backends/midi/ypa1.cpp @@ -117,7 +117,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices YamahaPa1MusicPlugin::getDevices() const { @@ -128,21 +128,12 @@ MusicDevices YamahaPa1MusicPlugin::getDevices() const { return devices; } -Common::Error YamahaPa1MusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error YamahaPa1MusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_YamahaPa1(); return Common::kNoError; } -MidiDriver *MidiDriver_YamahaPa1_create() { - MidiDriver *mididriver; - - YamahaPa1MusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(YPA1) //REGISTER_PLUGIN_DYNAMIC(YPA1, PLUGIN_TYPE_MUSIC, YamahaPa1MusicPlugin); //#else diff --git a/backends/midi/zodiac.cpp b/backends/midi/zodiac.cpp index b9cb46912a..e848315ca4 100644 --- a/backends/midi/zodiac.cpp +++ b/backends/midi/zodiac.cpp @@ -135,7 +135,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices ZodiacMusicPlugin::getDevices() const { @@ -146,21 +146,12 @@ MusicDevices ZodiacMusicPlugin::getDevices() const { return devices; } -Common::Error ZodiacMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error ZodiacMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_Zodiac(); return Common::kNoError; } -MidiDriver *MidiDriver_Zodiac_create() { - MidiDriver *mididriver; - - ZodiacMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(ZODIAC) //REGISTER_PLUGIN_DYNAMIC(ZODIAC, PLUGIN_TYPE_MUSIC, ZodiacMusicPlugin); //#else diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 1c548d3f50..8b0decf695 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -364,7 +364,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha END_OPTION DO_OPTION('e', "music-driver") - if (MidiDriver::findMusicDriver(option) == 0) + if (MidiDriver::getMusicType(MidiDriver::getDeviceHandle(option)) == MT_NULL) usage("Unrecognized music driver '%s'", option); END_OPTION diff --git a/base/plugins.cpp b/base/plugins.cpp index 6c80da65d4..199344087c 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -167,6 +167,7 @@ public: // Music plugins // TODO: Use defines to disable or enable each MIDI driver as a // static/dynamic plugin, like it's done for the engines + LINK_PLUGIN(AUTO) LINK_PLUGIN(NULL) #if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) LINK_PLUGIN(WINDOWS) diff --git a/common/util.cpp b/common/util.cpp index b8bd327a0a..70499a984f 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -305,7 +305,8 @@ const struct GameOpt { { GUIO_MIDIPCJR, "midiPCJr" }, { GUIO_MIDIADLIB, "midiAdLib" }, { GUIO_MIDITOWNS, "midiTowns" }, - { GUIO_MIDI, "midiMidi" }, + { GUIO_MIDIMT32, "midiMt32" }, + { GUIO_MIDIGM, "midiGM" }, { GUIO_NONE, 0 } }; diff --git a/common/util.h b/common/util.h index 71456353c7..d7d68cc1ca 100644 --- a/common/util.h +++ b/common/util.h @@ -223,8 +223,9 @@ enum GameGUIOption { GUIO_MIDICMS = (1 << 7), GUIO_MIDIPCJR = (1 << 8), GUIO_MIDIADLIB = (1 << 9), - GUIO_MIDITOWNS = (1 << 10), - GUIO_MIDI = (1 << 11) + GUIO_MIDITOWNS = (1 << 10), + GUIO_MIDIMT32 = (1 << 11), + GUIO_MIDIGM = (1 << 12) }; bool checkGameGUIOption(GameGUIOption option, const String &str); diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 6a359944e1..a39725a973 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -587,14 +587,14 @@ void AgiEngine::initialize() { } else if (getPlatform() == Common::kPlatformCoCo3) { _soundemu = SOUND_EMU_COCO3; } else { - switch (MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_PCJR | MDT_ADLIB | MDT_MIDI)) { - case MD_PCSPK: + switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK))) { + case MT_PCSPK: _soundemu = SOUND_EMU_PC; break; - case MD_PCJR: + case MT_PCJR: _soundemu = SOUND_EMU_PCJR; break; - case MD_ADLIB: + case MT_ADLIB: _soundemu = SOUND_EMU_NONE; break; default: diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp index 35285798d4..1a5698dffc 100644 --- a/engines/agi/preagi.cpp +++ b/engines/agi/preagi.cpp @@ -68,8 +68,8 @@ void PreAgiEngine::initialize() { // drivers, and I'm not sure what they are. For now, they might // as well be called "PC Speaker" and "Not PC Speaker". - switch (MidiDriver::detectMusicDriver(MDT_PCSPK)) { - case MD_PCSPK: + switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK))) { + case MT_PCSPK: _soundemu = SOUND_EMU_PC; break; default: diff --git a/engines/agi/sound_midi.cpp b/engines/agi/sound_midi.cpp index 551df527cc..57c5d54b27 100644 --- a/engines/agi/sound_midi.cpp +++ b/engines/agi/sound_midi.cpp @@ -71,8 +71,8 @@ MIDISound::MIDISound(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : A } SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _parser(0), _isPlaying(false), _passThrough(false), _isGM(false) { - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB); - _driver = MidiDriver::createMidi(midiDriver); + DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB); + _driver = MidiDriver::createMidi(dev); memset(_channel, 0, sizeof(_channel)); memset(_channelVolume, 255, sizeof(_channelVolume)); diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 926b3a8972..481c73dc5c 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -557,10 +557,10 @@ Common::Error AGOSEngine::init() { (getPlatform() == Common::kPlatformPC)) { // Setup midi driver - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_MIDI); - _nativeMT32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | (getGameType() == GType_SIMON1 ? MDT_PREFER_MT32 : MDT_PREFER_GM)); + _nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); - _driver = MidiDriver::createMidi(midiDriver); + _driver = MidiDriver::createMidi(dev); if (_nativeMT32) { _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp index cbf878279b..9e1e7033bb 100644 --- a/engines/draci/draci.cpp +++ b/engines/draci/draci.cpp @@ -127,11 +127,11 @@ int DraciEngine::init() { _dubbingArchive = new SoundArchive(dubbingPath, kDubbingFrequency); _sound = new Sound(_mixer); - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - //bool adlib = (midiDriver == MD_ADLIB); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); + //bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB); - _midiDriver = MidiDriver::createMidi(midiDriver); + _midiDriver = MidiDriver::createMidi(dev); if (native_mt32) _midiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index e3472e9fe1..fba616b166 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -345,8 +345,8 @@ void GobEngine::pauseGame() { } bool GobEngine::initGameParts() { - _noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL; - + // just detect some devices some of which will be always there if the music is not disabled + _noMusic = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB) ? false : true; _saveLoad = 0; _global = new Global(this); diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp index 2ea7454256..7166432e02 100644 --- a/engines/groovie/music.cpp +++ b/engines/groovie/music.cpp @@ -386,8 +386,8 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName) _midiParser = MidiParser::createParser_XMIDI(); // Create the driver - MidiDriverType driver = detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - _driver = createMidi(driver); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + _driver = createMidi(dev); this->open(); // Set the parser's driver @@ -402,9 +402,9 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName) } // Load the Global Timbre Library - if (driver == MD_ADLIB) { + if (MidiDriver::getMusicType(dev) == MT_ADLIB) { // MIDI through AdLib - _musicType = MD_ADLIB; + _musicType = MT_ADLIB; loadTimbres(gtlName + ".ad"); // Setup the percussion channel @@ -412,9 +412,9 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName) if (_timbres[i].bank == 0x7F) setTimbreAD(9, _timbres[i]); } - } else if ((driver == MD_MT32) || ConfMan.getBool("native_mt32")) { + } else if ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")) { // MT-32 - _musicType = MD_MT32; + _musicType = MT_MT32; loadTimbres(gtlName + ".mt"); } else { // GM @@ -455,9 +455,9 @@ void MusicPlayerXMI::send(uint32 b) { for (int i = 0; i < numTimbres; i++) { if ((_timbres[i].bank == _chanBanks[chan]) && (_timbres[i].patch == patch)) { - if (_musicType == MD_ADLIB) { + if (_musicType == MT_ADLIB) { setTimbreAD(chan, _timbres[i]); - } else if (_musicType == MD_MT32) { + } else if (_musicType == MT_MT32) { setTimbreMT(chan, _timbres[i]); } return; @@ -682,8 +682,8 @@ MusicPlayerMac::MusicPlayerMac(GroovieEngine *vm) : MusicPlayerMidi(vm) { _midiParser = MidiParser::createParser_SMF(); // Create the driver - MidiDriverType driver = detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - _driver = createMidi(driver); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + _driver = createMidi(dev); this->open(); // Set the parser's driver diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp index 297da6ccc2..08df5e7a83 100644 --- a/engines/groovie/script.cpp +++ b/engines/groovie/script.cpp @@ -86,11 +86,11 @@ Script::Script(GroovieEngine *vm, EngineVersion version) : } // Initialize the music type variable - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - if (midiDriver == MD_ADLIB) { + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + if (MidiDriver::getMusicType(dev) == MT_ADLIB) { // MIDI through AdLib setVariable(0x100, 0); - } else if ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")) { + } else if ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")) { // MT-32 setVariable(0x100, 2); } else { diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 00b32425c2..970851c127 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -106,7 +106,7 @@ Common::Error KyraEngine_v1::init() { if (!_flags.useDigSound) { // We prefer AdLib over MIDI, since generally AdLib is better supported - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_MIDI | MDT_ADLIB); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI | MDT_PREFER_MT32); if (_flags.platform == Common::kPlatformFMTowns) { if (_flags.gameID == GI_KYRA1) @@ -120,24 +120,24 @@ Common::Error KyraEngine_v1::init() { _sound = new SoundTownsPC98_v2(this, _mixer); } else if (_flags.platform == Common::kPlatformAmiga) { _sound = new SoundAmiga(this, _mixer); - } else if (midiDriver == MD_ADLIB) { + } else if (MidiDriver::getMusicType(dev) == MT_ADLIB) { _sound = new SoundAdLibPC(this, _mixer); } else { Sound::kType type; - if (midiDriver == MD_PCSPK) + if (MidiDriver::getMusicType(dev) == MT_PCSPK) type = Sound::kPCSpkr; - else if (midiDriver == MD_MT32 || ConfMan.getBool("native_mt32")) + else if (MidiDriver::getMusicType(dev) == MT_MT32 || ConfMan.getBool("native_mt32")) type = Sound::kMidiMT32; else type = Sound::kMidiGM; MidiDriver *driver = 0; - if (midiDriver == MD_PCSPK) { + if (MidiDriver::getMusicType(dev) == MT_PCSPK) { driver = new MidiDriver_PCSpeaker(_mixer); } else { - driver = MidiDriver::createMidi(midiDriver); + driver = MidiDriver::createMidi(dev); if (type == Sound::kMidiMT32) driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); } diff --git a/engines/lure/sound.cpp b/engines/lure/sound.cpp index e725b7c31a..1b306b5021 100644 --- a/engines/lure/sound.cpp +++ b/engines/lure/sound.cpp @@ -50,13 +50,13 @@ SoundManager::SoundManager() { _soundData = NULL; _paused = false; - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - _isRoland = midiDriver != MD_ADLIB; - _nativeMT32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + _isRoland = MidiDriver::getMusicType(dev) != MT_ADLIB; + _nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); Common::set_to(_channelsInUse, _channelsInUse + NUM_CHANNELS, false); - _driver = MidiDriver::createMidi(midiDriver); + _driver = MidiDriver::createMidi(dev); int statusCode = _driver->open(); if (statusCode) { warning("Sound driver returned error code %d", statusCode); diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp index 446f2bf974..8063044205 100644 --- a/engines/m4/m4.cpp +++ b/engines/m4/m4.cpp @@ -156,10 +156,10 @@ Common::Error MadsM4Engine::run() { // Initialize backend _screen = new M4Surface(true); // Special form for creating screen reference - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); - _driver = MidiDriver::createMidi(midiDriver); + _driver = MidiDriver::createMidi(dev); if (native_mt32) _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); diff --git a/engines/made/made.cpp b/engines/made/made.cpp index 54e2189471..b983e87cc2 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -97,11 +97,11 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng _script = new ScriptInterpreter(this); - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - //bool adlib = (midiDriver == MD_ADLIB); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); + //bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB); - MidiDriver *driver = MidiDriver::createMidi(midiDriver); + MidiDriver *driver = MidiDriver::createMidi(dev); if (native_mt32) driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp index b84573f011..5e1ea8cdb2 100644 --- a/engines/mohawk/sound.cpp +++ b/engines/mohawk/sound.cpp @@ -27,12 +27,12 @@ #include "common/util.h" +#include "sound/musicplugin.h" #include "sound/audiostream.h" #include "sound/decoders/mp3.h" #include "sound/decoders/raw.h" #include "sound/decoders/wave.h" - namespace Mohawk { Sound::Sound(MohawkEngine* vm) : _vm(vm) { @@ -79,7 +79,7 @@ void Sound::initMidi() { // Let's get our MIDI parser/driver _midiParser = MidiParser::createParser_SMF(); - _midiDriver = MidiDriver::createMidi(MidiDriver::detectMusicDriver(MDT_ADLIB|MDT_MIDI)); + _midiDriver = MidiDriver::createMidi(MidiDriver::detectDevice(MDT_ADLIB|MDT_MIDI)); // Set up everything! _midiDriver->open(); diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index 153ea1541d..6dbf526c96 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -61,8 +61,8 @@ Common::Error Parallaction_br::init() { _disk = new DosDisk_br(this); } _disk->setLanguage(2); // NOTE: language is now hardcoded to English. Original used command-line parameters. - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - MidiDriver *driver = MidiDriver::createMidi(midiDriver); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + MidiDriver *driver = MidiDriver::createMidi(dev); _soundManI = new DosSoundMan_br(this, driver); } else { _disk = new AmigaDisk_br(this); diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index c1d6c9367a..7e06aaa5ab 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -24,7 +24,6 @@ */ #include "common/system.h" - #include "common/config-manager.h" #include "parallaction/parallaction.h" @@ -167,8 +166,8 @@ Common::Error Parallaction_ns::init() { _disk->init(); if (getPlatform() == Common::kPlatformPC) { - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - MidiDriver *driver = MidiDriver::createMidi(midiDriver); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + MidiDriver *driver = MidiDriver::createMidi(dev); _soundManI = new DosSoundMan_ns(this, driver); _soundManI->setMusicVolume(ConfMan.getInt("music_volume")); } else { diff --git a/engines/queen/music.cpp b/engines/queen/music.cpp index b4b9210616..2bbbd53568 100644 --- a/engines/queen/music.cpp +++ b/engines/queen/music.cpp @@ -34,6 +34,7 @@ #include "sound/midiparser.h" + namespace Queen { extern MidiDriver *C_Player_CreateAdLibMidiDriver(Audio::Mixer *); @@ -45,9 +46,9 @@ MidiMusic::MidiMusic(QueenEngine *vm) _queuePos = _lastSong = _currentSong = 0; queueClear(); - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - _adlib = (midiDriver == MD_ADLIB); - _nativeMT32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI | MDT_PREFER_MT32); + _adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB); + _nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); const char *musicDataFile; if (vm->resource()->isDemo()) { @@ -72,7 +73,7 @@ MidiMusic::MidiMusic(QueenEngine *vm) // } _driver = C_Player_CreateAdLibMidiDriver(vm->_mixer); } else { - _driver = MidiDriver::createMidi(midiDriver); + _driver = MidiDriver::createMidi(dev); if (_nativeMT32) { _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); } diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 8b8f26d5a0..dbe79a3e72 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -47,8 +47,8 @@ MusicDriver::MusicDriver() : _isGM(false) { _masterVolume = 0; _nativeMT32 = ConfMan.getBool("native_mt32"); - _driverType = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - _driver = MidiDriver::createMidi(_driverType); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + _driver = MidiDriver::createMidi(dev); if (isMT32()) _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); diff --git a/engines/saga/music.h b/engines/saga/music.h index cb068cd835..5cce3d4c04 100644 --- a/engines/saga/music.h +++ b/engines/saga/music.h @@ -52,8 +52,8 @@ public: void setVolume(int volume); int getVolume() { return _masterVolume; } - bool isAdlib() { return _driverType == MD_ADLIB; } - bool isMT32() { return _driverType == MD_MT32 || _nativeMT32; } + bool isAdlib() { return _driverType == MT_ADLIB; } + bool isMT32() { return _driverType == MT_MT32 || _nativeMT32; } void setGM(bool isGM) { _isGM = isGM; } //MidiDriver interface implementation @@ -78,7 +78,7 @@ protected: MidiChannel *_channel[16]; MidiDriver *_driver; - MidiDriverType _driverType; + MusicType _driverType; byte _channelVolume[16]; bool _isGM; bool _nativeMT32; diff --git a/engines/sci/sound/drivers/fb01.cpp b/engines/sci/sound/drivers/fb01.cpp index 7e9fbd51a1..ab9b2e3df5 100644 --- a/engines/sci/sound/drivers/fb01.cpp +++ b/engines/sci/sound/drivers/fb01.cpp @@ -128,8 +128,8 @@ private: }; MidiPlayer_Fb01::MidiPlayer_Fb01(SciVersion version) : MidiPlayer(version), _playSwitch(true), _masterVolume(15), _timerParam(NULL), _timerProc(NULL) { - MidiDriverType midiType = MidiDriver::detectMusicDriver(MDT_MIDI); - _driver = createMidi(midiType); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI); + _driver = createMidi(dev); _sysExBuf[0] = 0x43; _sysExBuf[1] = 0x75; diff --git a/engines/sci/sound/drivers/midi.cpp b/engines/sci/sound/drivers/midi.cpp index 625874eea1..1ef0781906 100644 --- a/engines/sci/sound/drivers/midi.cpp +++ b/engines/sci/sound/drivers/midi.cpp @@ -120,10 +120,10 @@ private: }; MidiPlayer_Midi::MidiPlayer_Midi(SciVersion version) : MidiPlayer(version), _playSwitch(true), _masterVolume(15), _isMt32(false), _hasReverb(false), _isOldPatchFormat(true) { - MidiDriverType midiType = MidiDriver::detectMusicDriver(MDT_MIDI); - _driver = createMidi(midiType); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI); + _driver = createMidi(dev); - if (midiType == MD_MT32 || ConfMan.getBool("native_mt32")) + if (MidiDriver::getMusicType(dev) == MT_MT32 || ConfMan.getBool("native_mt32")) _isMt32 = true; _sysExBuf[0] = 0x41; diff --git a/engines/sci/sound/iterator/core.cpp b/engines/sci/sound/iterator/core.cpp index 7cd730b3e2..e2e62c83b7 100644 --- a/engines/sci/sound/iterator/core.cpp +++ b/engines/sci/sound/iterator/core.cpp @@ -223,7 +223,7 @@ void SfxPlayer::player_timer_callback(void *refCon) { /* API implementation */ Common::Error SfxPlayer::init(ResourceManager *resMan, int expected_latency) { - MidiDriverType musicDriver = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_ADLIB); + MidiDriverType musicDriver = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB); switch (musicDriver) { case MD_ADLIB: diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index fbf37a78b1..6c697c86e5 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -61,31 +61,25 @@ void SciMusic::init() { // SCI sound init _dwTempo = 0; - MidiDriverType midiType; - // Default to MIDI in SCI32 games, as many don't have AdLib support. // WORKAROUND: Default to MIDI in Amiga SCI1_EGA+ games as we don't support those patches yet. // We also don't yet support the 7.pat file of SCI1+ Mac games or SCI0 Mac patches, so we // default to MIDI in those games to let them run. Common::Platform platform = g_sci->getPlatform(); + uint32 dev = MidiDriver::detectDevice((getSciVersion() >= SCI_VERSION_2 || platform == Common::kPlatformMacintosh || (platform == Common::kPlatformAmiga && getSciVersion() >= SCI_VERSION_1_EGA)) ? (MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI) : (MDT_PCSPK | MDT_ADLIB | MDT_MIDI)); - if (getSciVersion() >= SCI_VERSION_2 || platform == Common::kPlatformMacintosh || (platform == Common::kPlatformAmiga && getSciVersion() >= SCI_VERSION_1_EGA)) - midiType = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI); - else - midiType = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_ADLIB | MDT_MIDI); - - switch (midiType) { - case MD_ADLIB: + switch (MidiDriver::getMusicType(dev)) { + case MT_ADLIB: // FIXME: There's no Amiga sound option, so we hook it up to AdLib if (g_sci->getPlatform() == Common::kPlatformAmiga) _pMidiDrv = MidiPlayer_Amiga_create(_soundVersion); else _pMidiDrv = MidiPlayer_AdLib_create(_soundVersion); break; - case MD_PCJR: + case MT_PCJR: _pMidiDrv = MidiPlayer_PCJr_create(_soundVersion); break; - case MD_PCSPK: + case MT_PCSPK: _pMidiDrv = MidiPlayer_PCSpeaker_create(_soundVersion); break; default: diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 551e4c70a7..f509cabb2c 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -896,7 +896,7 @@ GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const { } } - dg.setGUIOptions(x->game.guioptions | MidiDriver::midiDriverFlags2GUIO(x->game.midi)); + dg.setGUIOptions(x->game.guioptions | MidiDriver::musicType2GUIO(x->game.midi)); dg.appendGUIOptions(getGameGUIOptionsDescriptionLanguage(x->language)); detectedGames.push_back(dg); diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index db6d04b785..e9dfce8057 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -224,7 +224,7 @@ static const GameSettings gameVariantsTable[] = { {"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, {"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI}, - {"loom", "EGA", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_CMS | MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH}, + {"loom", "EGA", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, {"loom", "No AdLib", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_CMS, 0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI}, #ifdef USE_RGB_COLOR {"loom", "PC-Engine", 0, GID_LOOM, 3, 0, MDT_NONE, GF_AUDIOTRACKS | GF_OLD256 | GF_16BIT_COLOR, Common::kPlatformPCEngine, GUIO_NOSPEECH | GUIO_NOMIDI}, @@ -234,24 +234,24 @@ static const GameSettings gameVariantsTable[] = { {"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, - {"monkey", "VGA", "vga", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH}, - {"monkey", "EGA", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_CMS | MDT_ADLIB | MDT_MIDI, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH}, + {"monkey", "VGA", "vga", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, + {"monkey", "EGA", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_MT32, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH}, {"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK, GF_16COLOR, Common::kPlatformAtariST, GUIO_NOSPEECH | GUIO_NOMIDI}, {"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, {"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO_NOSPEECH | GUIO_NOMIDI}, {"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI}, {"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO_NOSPEECH | GUIO_NOMIDI}, - {"monkey2", 0, 0, GID_MONKEY2, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH}, + {"monkey2", 0, 0, GID_MONKEY2, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, - {"atlantis", "" , 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NONE}, - {"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH}, + {"atlantis", "" , 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NONE}, + {"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, - {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE}, - {"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH}, + {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO_NONE}, + {"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO_NOSPEECH}, - {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE}, - {"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH}, + {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO_NONE}, + {"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO_NOSPEECH}, #ifdef ENABLE_SCUMM_7_8 {"ft", 0, 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO_NOMIDI}, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 862353bf95..7c3b8a4a1d 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1634,28 +1634,28 @@ void ScummEngine_v100he::resetScumm() { #endif void ScummEngine::setupMusic(int midi) { - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(midi); - _native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(midi); + _native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); - switch (midiDriver) { - case MD_NULL: + switch (MidiDriver::getMusicType(dev)) { + case MT_NULL: _musicType = MDT_NONE; break; - case MD_PCSPK: - case MD_PCJR: + case MT_PCSPK: + case MT_PCJR: _musicType = MDT_PCSPK; break; - case MD_CMS: + //case MT_CMS: #if 1 _musicType = MDT_ADLIB; #else _musicType = MDT_CMS; // Still has number of bugs, disable by default #endif break; - case MD_TOWNS: + case MT_TOWNS: _musicType = MDT_TOWNS; break; - case MD_ADLIB: + case MT_ADLIB: _musicType = MDT_ADLIB; break; default: @@ -1707,7 +1707,7 @@ void ScummEngine::setupMusic(int midi) { if (!_mixer->isReady()) { warning("Sound mixer initialization failed"); if (_musicType == MDT_ADLIB || _musicType == MDT_PCSPK || _musicType == MDT_CMS) { - midiDriver = MD_NULL; + dev = 0; _musicType = MDT_NONE; warning("MIDI driver depends on sound mixer, switching to null MIDI driver"); } @@ -1735,11 +1735,11 @@ void ScummEngine::setupMusic(int midi) { } else if (_game.platform == Common::kPlatformAmiga && _game.version <= 4) { _musicEngine = new Player_V4A(this, _mixer); } else if (_game.id == GID_MANIAC && _game.version == 1) { - _musicEngine = new Player_V1(this, _mixer, midiDriver != MD_PCSPK); + _musicEngine = new Player_V1(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK); } else if (_game.version <= 2) { - _musicEngine = new Player_V2(this, _mixer, midiDriver != MD_PCSPK); + _musicEngine = new Player_V2(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK); } else if ((_musicType == MDT_PCSPK) && (_game.version > 2 && _game.version <= 4)) { - _musicEngine = new Player_V2(this, _mixer, midiDriver != MD_PCSPK); + _musicEngine = new Player_V2(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK); } else if (_musicType == MDT_CMS) { _musicEngine = new Player_V2CMS(this, _mixer); } else if (_game.platform == Common::kPlatform3DO && _game.heversion <= 62) { @@ -1749,12 +1749,12 @@ void ScummEngine::setupMusic(int midi) { MidiDriver *adlibMidiDriver = 0; if (_musicType != MDT_ADLIB) - nativeMidiDriver = MidiDriver::createMidi(midiDriver); + nativeMidiDriver = MidiDriver::createMidi(dev); if (nativeMidiDriver != NULL && _native_mt32) nativeMidiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); bool multi_midi = ConfMan.getBool("multi_midi") && _musicType != MDT_NONE && (midi & MDT_ADLIB); if (_musicType == MDT_ADLIB || multi_midi) { - adlibMidiDriver = MidiDriver_ADLIB_create(); + adlibMidiDriver = MidiDriver::createMidi(MidiDriver::detectDevice(MDT_ADLIB)); adlibMidiDriver->property(MidiDriver::PROP_OLD_ADLIB, (_game.features & GF_SMALL_HEADER) ? 1 : 0); } @@ -1769,7 +1769,7 @@ void ScummEngine::setupMusic(int midi) { // YM2162 driver can't handle midi->getPercussionChannel(), NULL shouldn't init MT-32/GM/GS if ((midi != MDT_TOWNS) && (midi != MDT_NONE)) { _imuse->property(IMuse::PROP_NATIVE_MT32, _native_mt32); - if (midiDriver != MD_MT32) // MT-32 Emulation shouldn't be GM/GS initialized + if (MidiDriver::getMusicType(dev) != MT_MT32) // MT-32 Emulation shouldn't be GM/GS initialized _imuse->property(IMuse::PROP_GS, _enable_gs); } if (_game.heversion >= 60 || midi == MDT_TOWNS) { diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp index 9ea20aafc6..58e3f5be2c 100644 --- a/engines/sky/sky.cpp +++ b/engines/sky/sky.cpp @@ -259,16 +259,16 @@ Common::Error SkyEngine::init() { _systemVars.gameVersion = _skyDisk->determineGameVersion(); - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI); - if (midiDriver == MD_ADLIB) { + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI | MDT_PREFER_MT32); + if (MidiDriver::getMusicType(dev) == MT_ADLIB) { _systemVars.systemFlags |= SF_SBLASTER; _skyMusic = new AdLibMusic(_mixer, _skyDisk); } else { _systemVars.systemFlags |= SF_ROLAND; - if ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")) - _skyMusic = new MT32Music(MidiDriver::createMidi(midiDriver), _skyDisk); + if ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")) + _skyMusic = new MT32Music(MidiDriver::createMidi(dev), _skyDisk); else - _skyMusic = new GmMusic(MidiDriver::createMidi(midiDriver), _skyDisk); + _skyMusic = new GmMusic(MidiDriver::createMidi(dev), _skyDisk); } if (isCDVersion()) { diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp index 8d11efef3c..e5a39308da 100644 --- a/engines/tinsel/tinsel.cpp +++ b/engines/tinsel/tinsel.cpp @@ -856,11 +856,11 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc) if (cd_num >= 0) _system->openCD(cd_num); - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - //bool adlib = (midiDriver == MD_ADLIB); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); + //bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB); - _driver = MidiDriver::createMidi(midiDriver); + _driver = MidiDriver::createMidi(dev); if (native_mt32) _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); diff --git a/engines/touche/midi.cpp b/engines/touche/midi.cpp index 9dbef4d76f..5c1d687827 100644 --- a/engines/touche/midi.cpp +++ b/engines/touche/midi.cpp @@ -92,9 +92,9 @@ void MidiPlayer::setVolume(int volume) { } int MidiPlayer::open() { - MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - _nativeMT32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - _driver = MidiDriver::createMidi(midiDriver); + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + _nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); + _driver = MidiDriver::createMidi(dev); int ret = _driver->open(); if (ret == 0) { _parser = MidiParser::createParser_SMF(); diff --git a/gui/options.cpp b/gui/options.cpp index 7a69c6a25f..41a82ca89c 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -40,6 +40,7 @@ #include "graphics/scaler.h" #include "sound/mididrv.h" +#include "sound/musicplugin.h" #include "sound/mixer.h" #include "sound/fmopl.h" @@ -99,6 +100,8 @@ void OptionsDialog::init() { _aspectCheckbox = 0; _enableAudioSettings = false; _midiPopUp = 0; + _mt32DevicePopUp = 0; + _gmDevicePopUp = 0; _oplPopUp = 0; _outputRatePopUp = 0; _enableMIDISettings = false; @@ -133,6 +136,20 @@ void OptionsDialog::init() { } } +template<class T> bool prdEqualsDeviceProperty(MusicDevices::iterator d, T lookupProp, Common::MemFunc0<T, MusicDevice> devicePropFunc) { + return lookupProp == devicePropFunc(&*d); +} + +bool prdMidiDefault(MusicDevices::iterator d, Common::String dom, bool, MusicPlugin::List::const_iterator&) { + return !(dom == Common::ConfigManager::kApplicationDomain && d->getMusicType() == MT_TOWNS) ? true : false; +} + +bool prdMidiSpec(MusicDevices::iterator d, Common::String, bool isAutoPlugin, MusicPlugin::List::const_iterator &m) { + if (isAutoPlugin) + m++; + return ((d->getMusicType() >= MT_GM) || isAutoPlugin) ? true : false; +} + void OptionsDialog::open() { Dialog::open(); @@ -191,10 +208,25 @@ void OptionsDialog::open() { } // Audio options - if (_midiPopUp) { - // Music driver - MidiDriverType id = MidiDriver::parseMusicDriver(ConfMan.get("music_driver", _domain)); - _midiPopUp->setSelectedTag(id); + if (!loadMusicDeviceSetting(_midiPopUp, "music_driver", prdMidiDefault)) + _midiPopUp->setSelected(0); + + if (!loadMusicDeviceSetting(_mt32DevicePopUp, "mt32_device", prdMidiSpec)) { + if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { + if (!loadMusicDeviceSetting(_mt32DevicePopUp, "", prdMidiSpec, MT_MT32)) + _mt32DevicePopUp->setSelected(0); + } else { + _mt32DevicePopUp->setSelected(0); + } + } + + if (!loadMusicDeviceSetting(_gmDevicePopUp, "gm_device", prdMidiSpec)) { + if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { + if (!loadMusicDeviceSetting(_gmDevicePopUp, "", prdMidiSpec, MT_GM)) + _gmDevicePopUp->setSelected(0); + } else { + _gmDevicePopUp->setSelected(0); + } } if (_oplPopUp) { @@ -332,19 +364,9 @@ void OptionsDialog::close() { } // Audio options - if (_midiPopUp) { - if (_enableAudioSettings) { - const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers(); - while (md->name && md->id != (int)_midiPopUp->getSelectedTag()) - md++; - if (md->name) - ConfMan.set("music_driver", md->name, _domain); - else - ConfMan.removeKey("music_driver", _domain); - } else { - ConfMan.removeKey("music_driver", _domain); - } - } + saveMusicDeviceSetting(_midiPopUp, "music_driver", prdMidiDefault); + saveMusicDeviceSetting(_mt32DevicePopUp, "mt32_device", prdMidiSpec); + saveMusicDeviceSetting(_gmDevicePopUp, "gm_device", prdMidiSpec); if (_oplPopUp) { if (_enableAudioSettings) { @@ -495,14 +517,17 @@ void OptionsDialog::setGraphicSettingsState(bool enabled) { void OptionsDialog::setAudioSettingsState(bool enabled) { _enableAudioSettings = enabled; - _midiPopUpDesc->setEnabled(enabled); _midiPopUp->setEnabled(enabled); + _mt32DevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _mt32DevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _gmDevicePopUpDesc->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); + _gmDevicePopUp->setEnabled(_domain.equals(Common::ConfigManager::kApplicationDomain) ? enabled : false); - uint32 allFlags = MidiDriver::midiDriverFlags2GUIO((uint32)-1); + uint32 allFlags = MidiDriver::musicType2GUIO((uint32)-1); if (_domain != Common::ConfigManager::kApplicationDomain && // global dialog - (_guioptions & allFlags) && // No flags are specified + (_guioptions & allFlags) && // No flags are specified !(_guioptions & Common::GUIO_MIDIADLIB)) { _oplPopUpDesc->setEnabled(false); _oplPopUp->setEnabled(false); @@ -623,19 +648,39 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &prefix) { // The MIDI mode popup & a label - _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _("Music driver:"), _("Specifies output sound device or sound card emulator")); + _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _(_domain == Common::ConfigManager::kApplicationDomain ? "Preferred Device:" : "Music Device:"), _(_domain == Common::ConfigManager::kApplicationDomain ? "Specifies preferred sound device or sound card emulator" : "Specifies output sound device or sound card emulator")); _midiPopUp = new PopUpWidget(boss, prefix + "auMidiPopup", _("Specifies output sound device or sound card emulator")); + _mt32DevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefMt32PopupDesc", _("MT32 Device:"), _("Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output")); + _mt32DevicePopUp = new PopUpWidget(boss, prefix + "auPrefMt32Popup"); + _gmDevicePopUpDesc = new StaticTextWidget(boss, prefix + "auPrefGmPopupDesc", _("GM Device:"), _("Specifies default sound device for General Midi output")); + _gmDevicePopUp = new PopUpWidget(boss, prefix + "auPrefGmPopup"); + // Populate it - const MidiDriverDescription *md = MidiDriver::getAvailableMidiDrivers(); - uint32 allFlags = MidiDriver::midiDriverFlags2GUIO((uint32)-1); - - while (md->name) { - if (_domain == Common::ConfigManager::kApplicationDomain || // global dialog - !(_guioptions & allFlags) || // No flags are specified - _guioptions & (MidiDriver::midiDriverFlags2GUIO(md->flags))) // flag is present - _midiPopUp->appendEntry(_(md->description), md->id); - md++; + uint32 allFlags = MidiDriver::musicType2GUIO((uint32)-1); + + const MusicPlugin::List p = MusicMan.getPlugins(); + int musicId = 0; + int midiId = 0; + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if ((_domain == Common::ConfigManager::kApplicationDomain && d->getMusicType() != MT_TOWNS) || // global dialog - skip useless FM-Towns option there + (_domain != Common::ConfigManager::kApplicationDomain && !(_guioptions & allFlags)) || // No flags are specified + _guioptions & (MidiDriver::musicType2GUIO(d->getMusicType()))) // flag is present + _midiPopUp->appendEntry(d->getCompleteName(), musicId++); + if (d->getMusicType() >= MT_GM || m == p.begin()) { + _mt32DevicePopUp->appendEntry(d->getCompleteName(), midiId); + _gmDevicePopUp->appendEntry(d->getCompleteName(), midiId++); + } + } + } + + if (!_domain.equals(Common::ConfigManager::kApplicationDomain)) { + _mt32DevicePopUpDesc->setEnabled(false); + _mt32DevicePopUp->setEnabled(false); + _gmDevicePopUpDesc->setEnabled(false); + _gmDevicePopUp->setEnabled(false); } // The OPL emulator popup & a label @@ -745,6 +790,60 @@ void OptionsDialog::addVolumeControls(GuiObject *boss, const Common::String &pre _enableVolumeSettings = true; } +bool OptionsDialog::loadMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MidiSettingsExtraPred pred, MusicType preferredType) { + if (!popup || !popup->isEnabled()) + return true; + + if (ConfMan.hasKey(setting, _domain) || preferredType) { + const Common::String drv = ConfMan.get(setting, _domain); + const MusicPlugin::List p = MusicMan.getPlugins(); + int id = 0; + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end() && id != -1; m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if ((setting.empty() && preferredType) ? prdEqualsDeviceProperty(d, preferredType, Common::mem_fun(&MusicDevice::getMusicType)) : prdEqualsDeviceProperty(d, drv, Common::mem_fun(&MusicDevice::getCompleteId))) { + popup->setSelected(id); + id = -1; + break; + } else if (pred(d, _domain, m == p.begin(), m)) { + id++; + } + } + } + if (id != -1) + // midi device turned off or whatever + return false; + } else { + return false; + } + + return true; +} + +void OptionsDialog::saveMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MidiSettingsExtraPred pred) { + if (!popup || !_enableAudioSettings) + return; + + const MusicPlugin::List p = MusicMan.getPlugins(); + uint32 id = 0; + bool found = false; + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end() && !found; m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (id == popup->getSelectedTag()) { + ConfMan.set(setting, d->getCompleteId(), _domain); + found = true; + break; + } else if (pred(d, _domain, m == p.begin(), m)) { + id++; + } + } + } + + if (!found) + ConfMan.removeKey(setting, _domain); +} + int OptionsDialog::getSubtitleMode(bool subtitles, bool speech_mute) { if (_guioptions & Common::GUIO_NOSUBTITLES) return kSubtitlesSpeech; // Speech only diff --git a/gui/options.h b/gui/options.h index cc62a309b4..268b535e8a 100644 --- a/gui/options.h +++ b/gui/options.h @@ -28,6 +28,7 @@ #include "gui/dialog.h" #include "gui/TabWidget.h" #include "common/str.h" +#include "sound/musicplugin.h" #ifdef SMALL_SCREEN_DEVICE #include "gui/KeysDialog.h" @@ -78,6 +79,10 @@ protected: void setVolumeSettingsState(bool enabled); void setSubtitleSettingsState(bool enabled); + typedef bool (MidiSettingsExtraPred)(MusicDevices::iterator, Common::String, bool, MusicPlugin::List::const_iterator&); + bool loadMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MidiSettingsExtraPred pred, MusicType preferredType = MT_NULL); + void saveMusicDeviceSetting(PopUpWidget *popup, Common::String setting, MidiSettingsExtraPred pred); + TabWidget *_tabWidget; int _graphicsTabId; @@ -104,6 +109,13 @@ private: StaticTextWidget *_outputRatePopUpDesc; PopUpWidget *_outputRatePopUp; + StaticTextWidget *_mt32DevicePopUpDesc; + PopUpWidget *_mt32DevicePopUp; + StaticTextWidget *_gmDevicePopUpDesc; + PopUpWidget *_gmDevicePopUp; + + + // // MIDI controls // diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 7d80884073..9554bdf799 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -615,6 +615,22 @@ "/> " "</layout> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<widget name='auPrefMt32PopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefMt32Popup' " +"type='PopUp' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<widget name='auPrefGmPopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefGmPopup' " +"type='PopUp' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -1370,6 +1386,22 @@ "/> " "</layout> " "<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<widget name='auPrefMt32PopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefMt32Popup' " +"type='PopUp' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<widget name='auPrefGmPopupDesc' " +"type='OptionsLabel' " +"/> " +"<widget name='auPrefGmPopup' " +"type='PopUp' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex 080bed0612..67b3d7c041 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 56fa793797..80bc4bf41e 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -232,6 +232,22 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index 46156aa21c..64ac6e200a 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -230,6 +230,22 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex 5139fcd573..fb01518e82 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 0025722731..bd514acd85 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -247,6 +247,22 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx index 4532b44a06..8bb31e9f8a 100644 --- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx +++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx @@ -228,6 +228,22 @@ /> </layout> <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefMt32PopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefMt32Popup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> + <widget name = 'auPrefGmPopupDesc' + type = 'OptionsLabel' + /> + <widget name = 'auPrefGmPopup' + type = 'PopUp' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'> <widget name = 'auOPLPopupDesc' type = 'OptionsLabel' /> diff --git a/po/POTFILES b/po/POTFILES index 8150006eaa..6e42829523 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -21,7 +21,11 @@ engines/dialogs.cpp engines/scumm/dialogs.cpp engines/mohawk/dialogs.cpp -sound/mididrv.cpp +sound/musicplugin.cpp +sound/null.cpp +sound/softsynth/mt32.cpp +sound/softsynth/adlib.cpp +sound/softsynth/ym2612.cpp backends/keymapper/remap-dialog.cpp backends/platform/ds/arm9/source/dsoptions.cpp diff --git a/sound/mididrv.cpp b/sound/mididrv.cpp index c6e208ae47..51abed3aa1 100644 --- a/sound/mididrv.cpp +++ b/sound/mididrv.cpp @@ -27,96 +27,10 @@ #include "common/config-manager.h" #include "common/str.h" #include "common/system.h" -#include "common/translation.h" #include "common/util.h" #include "sound/mididrv.h" - -static const uint32 GUIOMapping[] = { - MDT_PCSPK, Common::GUIO_MIDIPCSPK, - MDT_CMS, Common::GUIO_MIDICMS, - MDT_PCJR, Common::GUIO_MIDIPCJR, - MDT_ADLIB, Common::GUIO_MIDIADLIB, - MDT_TOWNS, Common::GUIO_MIDITOWNS, - MDT_MIDI, Common::GUIO_MIDI, - 0, 0 -}; - -uint32 MidiDriver::midiDriverFlags2GUIO(uint32 flags) { - uint32 res = 0; - - for (int i = 0; GUIOMapping[i] || GUIOMapping[i + 1]; i += 2) { - if (flags & GUIOMapping[i]) - res |= GUIOMapping[i + 1]; - } - - return res; -} - -/** Internal list of all available 'midi' drivers. */ -static const MidiDriverDescription s_musicDrivers[] = { - - // The flags for the "auto" & "null" drivers indicate that they are anything - // you want it to be. - {"auto", _s("<default>"), MD_AUTO, MDT_MIDI | MDT_PCSPK | MDT_ADLIB | MDT_TOWNS}, - {"null", _s("No music"), MD_NULL, MDT_MIDI | MDT_PCSPK | MDT_ADLIB | MDT_TOWNS}, - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - {"windows", _s("Windows MIDI"), MD_WINDOWS, MDT_MIDI}, -#endif - -#if defined(UNIX) && defined(USE_ALSA) - {"alsa", _s("ALSA"), MD_ALSA, MDT_MIDI}, -#endif - -#if defined(__MINT__) - {"stmidi", _s("Atari ST MIDI"), MD_STMIDI, MDT_MIDI}, -#endif - -#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOSX) && !defined(__MAEMO__) && !defined(__MINT__) - {"seq", _s("SEQ"), MD_SEQ, MDT_MIDI}, -#endif - -#if defined(IRIX) - {"dmedia", _s("DMedia"), MD_DMEDIA, MDT_MIDI}, -#endif - -#if defined(__amigaos4__) - {"camd", _s("CAMD"), MD_CAMD, MDT_MIDI}, -#endif - -#if defined(MACOSX) - {"core", _s("CoreAudio"), MD_COREAUDIO, MDT_MIDI}, -// {"coreaudio", "CoreAudio", MD_COREAUDIO, MDT_MIDI}, - {"coremidi", _s("CoreMIDI"), MD_COREMIDI, MDT_MIDI}, -#endif - -#if defined(PALMOS_MODE) -# if defined(COMPILE_CLIE) - {"ypa1", _s("Yamaha Pa1"), MD_YPA1, MDT_MIDI}, -# elif defined(COMPILE_ZODIAC) && (!defined(ENABLE_SCUMM) || !defined(PALMOS_ARM)) - {"zodiac", _s("Tapwave Zodiac"), MD_ZODIAC, MDT_MIDI}, -# endif -#endif - -#ifdef USE_FLUIDSYNTH - {"fluidsynth", _s("FluidSynth"), MD_FLUIDSYNTH, MDT_MIDI}, -#endif -#ifdef USE_MT32EMU - {"mt32", _s("MT-32 Emulation"), MD_MT32, MDT_MIDI}, -#endif - - // The flags for the "adlib" driver indicates that it can do AdLib and MIDI. - {"adlib", _s("AdLib"), MD_ADLIB, MDT_ADLIB}, - {"pcspk", _s("PC Speaker"), MD_PCSPK, MDT_PCSPK}, - {"pcjr", _s("IBM PCjr"), MD_PCJR, MDT_PCSPK | MDT_PCJR}, - {"cms", _s("Creative Music System"), MD_CMS, MDT_CMS}, - {"towns", _s("FM Towns"), MD_TOWNS, MDT_TOWNS}, -#if defined(UNIX) - {"timidity", _s("TiMidity"), MD_TIMIDITY, MDT_MIDI}, -#endif - - {0, 0, MD_NULL, MDT_NONE} -}; +#include "sound/musicplugin.h" +#include "common/translation.h" const byte MidiDriver::_mt32ToGm[128] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F @@ -142,169 +56,190 @@ const byte MidiDriver::_gmToMt32[128] = { 101, 103, 100, 120, 117, 113, 99, 128, 128, 128, 128, 124, 123, 128, 128, 128, // 7x }; -const MidiDriverDescription *MidiDriver::getAvailableMidiDrivers() { - return s_musicDrivers; -} +static const uint32 GUIOMapping[] = { + MT_PCSPK, Common::GUIO_MIDIPCSPK, + /*MDT_CMS, Common::GUIO_MIDICMS,*/ + MT_PCJR, Common::GUIO_MIDIPCJR, + MT_ADLIB, Common::GUIO_MIDIADLIB, + MT_TOWNS, Common::GUIO_MIDITOWNS, + MT_GM, Common::GUIO_MIDIGM, + MT_MT32, Common::GUIO_MIDIMT32, + 0, 0 +}; + +uint32 MidiDriver::musicType2GUIO(uint32 musicType) { + uint32 res = 0; -const MidiDriverDescription *MidiDriver::findMusicDriver(const Common::String &str) { - if (str.empty()) - return 0; + for (int i = 0; GUIOMapping[i] || GUIOMapping[i + 1]; i += 2) { + if (musicType == GUIOMapping[i] || musicType == (uint32)-1) + res |= GUIOMapping[i + 1]; + } - const char *s = str.c_str(); - int len = 0; - const MidiDriverDescription *md = s_musicDrivers; + return res; +} - // Scan for string end or a colon - while (s[len] != 0 && s[len] != ':') - len++; +bool MidiDriver::_forceTypeMT32 = false; - while (md->name) { - // Compare the string passed to us with the current table entry. - // We ignore any characters following an (optional) colon ':' - // contained in str. - if (!scumm_strnicmp(md->name, s, len)) { - return md; +MusicType MidiDriver::getMusicType(MidiDriver::DeviceHandle handle) { + if (_forceTypeMT32) + return MT_MT32; + + if (handle) { + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (handle == d->getHandle()) + return d->getMusicType(); + } } - md++; } - - return 0; + + return MT_NULL; } -static MidiDriverType getDefaultMIDIDriver() { -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - return MD_WINDOWS; -#elif defined(MACOSX) - return MD_COREAUDIO; -#elif defined(PALMOS_MODE) - #if defined(COMPILE_CLIE) - return MD_YPA1; - #elif defined(COMPILE_ZODIAC) - return MD_ZODIAC; - #else - return MD_NULL; - #endif -#else - return MD_NULL; -#endif -} +Common::String MidiDriver::getDeviceString(DeviceHandle handle, DeviceStringType type) { + if (handle) { + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (handle == d->getHandle()) { + if (type == kDriverName) + return d->getMusicDriverName(); + else if (type == kDriverId) + return d->getMusicDriverId(); + else if (type == kDeviceId) + return d->getCompleteId(); + else + return Common::String("auto"); + } + } + } + } -MidiDriverType MidiDriver::parseMusicDriver(const Common::String &str) { - const MidiDriverDescription *md = findMusicDriver(str); - if (md) - return md->id; - return MD_AUTO; + return Common::String("auto"); } -MidiDriverType MidiDriver::detectMusicDriver(int flags) { - MidiDriverType musicDriver; +MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { + // Query the selected music device (defaults to MT_AUTO device). + DeviceHandle hdl = getDeviceHandle(ConfMan.get("music_driver")); - // Query the selected music driver (defaults to MD_AUTO). - const MidiDriverDescription *md = findMusicDriver(ConfMan.get("music_driver")); + _forceTypeMT32 = false; // Check whether the selected music driver is compatible with the // given flags. - if (!md || !(md->flags & flags)) - musicDriver = MD_AUTO; - else - musicDriver = md->id; - - // If the selected driver is MD_AUTO, we try to determine - // a suitable and "optimal" music driver. - if (musicDriver == MD_AUTO) { - - if (flags & MDT_PREFER_MIDI) { - // A MIDI music driver is preferred. Of course this implies - // that MIDI is actually listed in flags, so we verify that. - assert(flags & MDT_MIDI); + switch (getMusicType(hdl)) { + case MT_PCSPK: + case MT_PCJR: + if (flags & MDT_PCSPK) + return hdl; + break; + + case MT_ADLIB: + if (flags & MDT_ADLIB) + return hdl; + break; + + case MT_TOWNS: + if (flags & MDT_TOWNS) + return hdl; + break; + + case MT_GM: + case MT_GS: + case MT_MT32: + if (flags & MDT_MIDI) + return hdl; + case MT_NULL: + if (getDeviceString(hdl, MidiDriver::kDriverId).equals("null")) + return 0; - // Query the default MIDI driver. It's possible that there - // is none, in which case we revert to AUTO mode. - musicDriver = getDefaultMIDIDriver(); - if (musicDriver == MD_NULL) - musicDriver = MD_AUTO; - } - - if (musicDriver == MD_AUTO) { - // MIDI is not preferred, or no default MIDI device is available. - // In this case we first try the alternate drivers before checking - // for a 'real' MIDI driver. + default: + break; + } - if (flags & MDT_TOWNS) - musicDriver = MD_TOWNS; - else if (flags & MDT_ADLIB) - musicDriver = MD_ADLIB; - else if (flags & MDT_PCSPK) - musicDriver = MD_PCJR; - else if (flags & MDT_MIDI) - musicDriver = getDefaultMIDIDriver(); - else - musicDriver = MD_NULL; + // If the selected driver did not match the flags setting, + // we try to determine a suitable and "optimal" music driver. + const MusicPlugin::List p = MusicMan.getPlugins(); + // If only MDT_MIDI but not MDT_PREFER_MIDI is set we prefer the other devices (which will always be + // detected since they are hard coded and cannot be disabled. + for (int l = (flags & MDT_PREFER_MIDI) ? 1 : 0; l < 2; l++) { + if ((flags & MDT_MIDI) && (l == 1)) { + // If a preferred MT32 or GM device has been selected that device gets returned + hdl = getDeviceHandle(ConfMan.get((flags & MDT_PREFER_MT32) ? "mt32_device" : ((flags & MDT_PREFER_GM) ? "gm_device" : "auto"), Common::ConfigManager::kApplicationDomain)); + if (getMusicType(hdl) != MT_NULL) { + if (flags & MDT_PREFER_MT32) + // If we have a preferred MT32 device we disable the gm/mt32 mapping (more about this in mididrv.h) + _forceTypeMT32 = true; + + return hdl; + } + + // If we have no specific device selected (neither in the scummvm nor in the game domain) + // and no preferred MT32 or GM device selected we arrive here. + // If MT32 is preferred we try for the first available device with music type 'MT_MT32' (usually the mt32 emulator) + if (flags & MDT_PREFER_MT32) { + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (getMusicType(hdl) == MT_MT32) + return hdl; + } + } + } + + // Now we default to the first available device with music type 'MT_GM' + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (getMusicType(hdl) == MT_GM || getMusicType(hdl) == MT_GS) + return hdl; + } + } + } + + MusicType tp = MT_NULL; + if (flags & MDT_TOWNS) + tp = MT_TOWNS; + else if (flags & MDT_ADLIB) + tp = MT_ADLIB; + else if (flags & MDT_PCSPK) + tp = MT_PCSPK; + else + tp = MT_NULL; + + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (d->getMusicType() == tp) + return d->getHandle(); + } } } - return musicDriver; + return hdl; } -MidiDriver *MidiDriver::createMidi(MidiDriverType midiDriver) { - switch (midiDriver) { - case MD_NULL: return MidiDriver_NULL_create(); - - case MD_ADLIB: return MidiDriver_ADLIB_create(); - - case MD_TOWNS: return MidiDriver_YM2612_create(); - - // Right now PC Speaker and PCjr are handled - // outside the MidiDriver architecture, so - // don't create anything for now. - case MD_PCSPK: - case MD_CMS: - case MD_PCJR: return NULL; - -#ifdef USE_FLUIDSYNTH - case MD_FLUIDSYNTH: return MidiDriver_FluidSynth_create(); -#endif - -#ifdef USE_MT32EMU - case MD_MT32: return MidiDriver_MT32_create(); -#endif - -#if defined(PALMOS_MODE) -#if defined(COMPILE_CLIE) - case MD_YPA1: return MidiDriver_YamahaPa1_create(); -#elif defined(COMPILE_ZODIAC) && (!defined(ENABLE_SCUMM) || !defined(PALMOS_ARM)) - case MD_ZODIAC: return MidiDriver_Zodiac_create(); -#endif -#endif - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - case MD_WINDOWS: return MidiDriver_WIN_create(); -#endif -#if defined(__MINT__) - case MD_STMIDI: return MidiDriver_STMIDI_create(); -#endif -#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOSX) && !defined(__MAEMO__) && !defined(__MINT__) - case MD_SEQ: return MidiDriver_SEQ_create(); -#endif -#if defined(UNIX) - case MD_TIMIDITY: return MidiDriver_TIMIDITY_create(); -#endif -#if defined(IRIX) - case MD_DMEDIA: return MidiDriver_DMEDIA_create(); -#endif -#if defined(MACOSX) - case MD_COREAUDIO: return MidiDriver_CORE_create(); - case MD_COREMIDI: return MidiDriver_CoreMIDI_create(); -#endif -#if defined(UNIX) && defined(USE_ALSA) - case MD_ALSA: return MidiDriver_ALSA_create(); -#endif -#if defined(__amigaos4__) - case MD_CAMD: return MidiDriver_CAMD_create(); -#endif - default: - error("Invalid midi driver selected"); +MidiDriver *MidiDriver::createMidi(MidiDriver::DeviceHandle handle) { + MidiDriver *driver = 0; + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + if (getDeviceString(handle, MidiDriver::kDriverId).equals((**m)->getId())) + (**m)->createInstance(&driver, handle); } + return driver; +} + +MidiDriver::DeviceHandle MidiDriver::getDeviceHandle(const Common::String &identifier) { + const MusicPlugin::List p = MusicMan.getPlugins(); + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); m++) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) { + if (identifier.equals(d->getCompleteId()) || identifier.equals(d->getCompleteName())) + return d->getHandle(); + } + } - return NULL; + return getDeviceHandle("auto"); } diff --git a/sound/mididrv.h b/sound/mididrv.h index 2931e2571e..ee8ef449f0 100644 --- a/sound/mididrv.h +++ b/sound/mididrv.h @@ -30,6 +30,8 @@ #include "common/timer.h" class MidiChannel; +class MusicDevice; + namespace Audio { class Mixer; } @@ -43,56 +45,28 @@ namespace Common { class String; } * * @todo Rename MidiDriverType to MusicDriverType */ -enum MidiDriverType { - // Pseudo drivers - MD_AUTO, - MD_NULL, - - // Windows - MD_WINDOWS, - - // Atari ST - MD_STMIDI, - - // Linux - MD_ALSA, - MD_SEQ, - - // Mac OS X - MD_QTMUSIC, - MD_COREAUDIO, - MD_COREMIDI, - - // PalmOS - MD_YPA1, - MD_ZODIAC, - - // IRIX - MD_DMEDIA, - - // AMIGAOS4 - MD_CAMD, - - // MIDI softsynths - MD_FLUIDSYNTH, - MD_MT32, - - // "Fake" MIDI devices - MD_ADLIB, - MD_PCSPK, - MD_CMS, - MD_PCJR, - MD_TOWNS, - MD_TIMIDITY + +/** + * Music types that music drivers can implement and engines can rely on. + */ +enum MusicType { + MT_NULL = 0, // Null / Auto + MT_PCSPK = 1, // PC Speaker + MT_PCJR = 2, // PCjr + MT_ADLIB = 3, // AdLib + MT_TOWNS = 4, // FM-TOWNS + MT_GM = 5, // General MIDI + MT_MT32 = 6, // MT-32 + MT_GS = 7 // Roland GS }; /** - * A set of flags to be passed to detectMusicDriver() which can be used to + * A set of flags to be passed to detectDevice() which can be used to * specify what kind of music driver is preferred / accepted. * * The flags (except for MDT_PREFER_MIDI) indicate whether a given driver * type is acceptable. E.g. the TOWNS music driver could be returned by - * detectMusicDriver if and only if MDT_TOWNS is specified. + * detectDevice if and only if MDT_TOWNS is specified. * * @todo Rename MidiDriverFlags to MusicDriverFlags */ @@ -104,7 +78,9 @@ enum MidiDriverFlags { MDT_ADLIB = 1 << 3, // AdLib: Maps to MD_ADLIB MDT_TOWNS = 1 << 4, // FM-TOWNS: Maps to MD_TOWNS MDT_MIDI = 1 << 5, // Real MIDI - MDT_PREFER_MIDI = 1 << 6 // Real MIDI output is preferred + MDT_PREFER_MIDI = 1 << 6, // Real MIDI output is preferred + MDT_PREFER_MT32 = 1 << 7, // MT-32 output is preferred + MDT_PREFER_GM = 1 << 8 // GM output is preferred }; /** @@ -114,12 +90,6 @@ enum MidiDriverFlags { * * @todo Rename MidiDriverType to MusicDriverType */ -struct MidiDriverDescription { - const char *name; - const char *description; - MidiDriverType id; // A unique ID for each driver - int flags; // Capabilities of this driver -}; /** * Abstract MIDI Driver Class @@ -128,24 +98,41 @@ struct MidiDriverDescription { */ class MidiDriver { public: - /** Find the music driver matching the given driver name/description. */ - static const MidiDriverDescription *findMusicDriver(const Common::String &str); + typedef uint32 DeviceHandle; - /** Get the id of the music driver matching the given driver name, or MD_AUTO if there is no match. */ - static MidiDriverType parseMusicDriver(const Common::String &str); + enum DeviceStringType { + kDriverName, + kDriverId, + kDeviceId + }; - static uint32 midiDriverFlags2GUIO(uint32 flags); + static uint32 musicType2GUIO(uint32 musicType); + /** Create music driver matching the given device handle, or MT_AUTO if there is no match. */ + static MidiDriver *createMidi(DeviceHandle handle); + + /** Returnd device handle based on the present devices and the flags parameter. + / * Returns NULl if the matching device is the null or auto device. */ + static DeviceHandle detectDevice(int flags); + /** - * Get a list of all available MidiDriver types. - * @return list of all available midi drivers, terminated by a zero entry + * Find the music driver matching the given driver name/description. */ - static const MidiDriverDescription *getAvailableMidiDrivers(); + static DeviceHandle getDeviceHandle(const Common::String &identifier); - static MidiDriver *createMidi(MidiDriverType midiDriver); + /** Get the music type matching the given device handle, or MT_AUTO if there is no match. */ + static MusicType getMusicType(DeviceHandle handle); - static MidiDriverType detectMusicDriver(int flags); + /** Get the device string matching the given device handle and the given type. */ + static Common::String getDeviceString(DeviceHandle handle, DeviceStringType type); +private: + // If detectDevice() detects MT32 and we have a preferred MT32 device + // we use this to force getMusicType() to return MT_MT32 so that we don't + // have to rely on the 'True Roland MT-32' config manager setting (since nobody + // would possibly think about activating 'True Roland MT-32' when he has set + // 'Music Driver' to '>default>') + static bool _forceTypeMT32; public: virtual ~MidiDriver() { } @@ -274,28 +261,4 @@ public: virtual void sysEx_customInstrument(uint32 type, const byte *instr) = 0; }; - -// Factory functions, for faster compile -extern MidiDriver *MidiDriver_NULL_create(); -extern MidiDriver *MidiDriver_ADLIB_create(); -extern MidiDriver *MidiDriver_WIN_create(); -extern MidiDriver *MidiDriver_STMIDI_create(); -extern MidiDriver *MidiDriver_SEQ_create(); -extern MidiDriver *MidiDriver_TIMIDITY_create(); -extern MidiDriver *MidiDriver_QT_create(); -extern MidiDriver *MidiDriver_CORE_create(); -extern MidiDriver *MidiDriver_CoreMIDI_create(); -extern MidiDriver *MidiDriver_ALSA_create(); -extern MidiDriver *MidiDriver_DMEDIA_create(); -extern MidiDriver *MidiDriver_CAMD_create(); -extern MidiDriver *MidiDriver_YM2612_create(); -#ifdef USE_FLUIDSYNTH -extern MidiDriver *MidiDriver_FluidSynth_create(); -#endif -#ifdef USE_MT32EMU -extern MidiDriver *MidiDriver_MT32_create(); -#endif -extern MidiDriver *MidiDriver_YamahaPa1_create(); -extern MidiDriver *MidiDriver_Zodiac_create(); - #endif diff --git a/sound/musicplugin.cpp b/sound/musicplugin.cpp index b4754230da..7b5b6608ea 100644 --- a/sound/musicplugin.cpp +++ b/sound/musicplugin.cpp @@ -24,10 +24,12 @@ */ #include "sound/musicplugin.h" +#include "common/hash-str.h" +#include "common/translation.h" MusicDevice::MusicDevice(MusicPluginObject const *musicPlugin, Common::String name, MusicType mt) : - _musicDriverName(musicPlugin->getName()), _musicDriverId(musicPlugin->getId()), - _name(name), _type(mt) { + _musicDriverName(_(musicPlugin->getName())), _musicDriverId(musicPlugin->getId()), + _name(_(name)), _type(mt) { } Common::String MusicDevice::getCompleteName() { @@ -46,3 +48,19 @@ Common::String MusicDevice::getCompleteName() { return name; } + +Common::String MusicDevice::getCompleteId() { + Common::String id = _musicDriverId; + if (!_name.empty()) { + id += "_"; + id += _name; + } + + return id; +} + +MidiDriver::DeviceHandle MusicDevice::getHandle() { + if (_musicDriverId.equals("auto") || _musicDriverId.equals("null")) + return 0; + return (MidiDriver::DeviceHandle)Common::hashit(getCompleteId().c_str()); +} diff --git a/sound/musicplugin.h b/sound/musicplugin.h index df97494a90..3823f2fd3d 100644 --- a/sound/musicplugin.h +++ b/sound/musicplugin.h @@ -29,19 +29,6 @@ #include "sound/mididrv.h" #include "common/list.h" -/** - * Music types that music drivers can implement and engines can rely on. - */ -enum MusicType { - MT_PCSPK = 1, // PC Speaker - MT_PCJR = 2, // PCjr - MT_ADLIB = 3, // AdLib - MT_TOWNS = 4, // FM-TOWNS - MT_GM = 5, // General MIDI - MT_MT32 = 6, // MT-32 - MT_GS = 7 // Roland GS -}; - class MusicPluginObject; /** @@ -63,6 +50,14 @@ public: * device name (if it isn't the default one) and the name of the driver. */ Common::String getCompleteName(); + + /** + * Returns a user readable string that contains the name of the current + * device name (if it isn't the default one) and the id of the driver. + */ + Common::String getCompleteId(); + + MidiDriver::DeviceHandle getHandle(); private: Common::String _name; @@ -94,15 +89,18 @@ public: virtual MusicDevices getDevices() const = 0; /** - * Tries to instantiate a MIDI Driver instance based on the settings of - * the currently active ConfMan target. That is, the MusicPluginObject - * should query the ConfMan singleton for the device name, port, etc. + * Tries to instantiate a MIDI Driver instance based on the device + * previously detected via MidiDriver::detectDevice() * * @param mididriver Pointer to a pointer which the MusicPluginObject sets * to the newly create MidiDriver, or 0 in case of an error + * + * @param dev Pointer to a device to be used then creating the driver instance. + * Default value of zero for driver types without devices. + * * @return a Common::Error describing the error which occurred, or kNoError */ - virtual Common::Error createInstance(MidiDriver **mididriver) const = 0; + virtual Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const = 0; }; diff --git a/sound/null.cpp b/sound/null.cpp index 00a5f5e488..775a0e2fcb 100644 --- a/sound/null.cpp +++ b/sound/null.cpp @@ -24,6 +24,7 @@ #include "sound/musicplugin.h" #include "sound/mpu401.h" +#include "common/translation.h" /* NULL driver */ class MidiDriver_NULL : public MidiDriver_MPU401 { @@ -37,19 +38,19 @@ public: class NullMusicPlugin : public MusicPluginObject { public: - const char *getName() const { - return "No music"; + virtual const char *getName() const { + return _s("No music"); } - const char *getId() const { + virtual const char *getId() const { return "null"; } - MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + virtual MusicDevices getDevices() const; + virtual Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; -Common::Error NullMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error NullMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_NULL(); return Common::kNoError; @@ -57,28 +58,24 @@ Common::Error NullMusicPlugin::createInstance(MidiDriver **mididriver) const { MusicDevices NullMusicPlugin::getDevices() const { MusicDevices devices; - // TODO: return a different music type? - devices.push_back(MusicDevice(this, "", MT_GM)); + devices.push_back(MusicDevice(this, _s(""), MT_NULL)); return devices; } -MidiDriver *MidiDriver_NULL_create() { - MidiDriver *mididriver; - - NullMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} +class AutoMusicPlugin : public NullMusicPlugin { +public: + const char *getName() const { + return _s("<default>"); + } -#ifdef DISABLE_ADLIB -MidiDriver *MidiDriver_ADLIB_create() { - return MidiDriver_NULL_create(); -} -#endif + const char *getId() const { + return "auto"; + } +}; //#if PLUGIN_ENABLED_DYNAMIC(NULL) //REGISTER_PLUGIN_DYNAMIC(NULL, PLUGIN_TYPE_MUSIC, NullMusicPlugin); //#else + REGISTER_PLUGIN_STATIC(AUTO, PLUGIN_TYPE_MUSIC, AutoMusicPlugin); REGISTER_PLUGIN_STATIC(NULL, PLUGIN_TYPE_MUSIC, NullMusicPlugin); //#endif diff --git a/sound/softsynth/adlib.cpp b/sound/softsynth/adlib.cpp index 6697cef646..ffb359e816 100644 --- a/sound/softsynth/adlib.cpp +++ b/sound/softsynth/adlib.cpp @@ -27,6 +27,7 @@ #include "common/util.h" #include "sound/fmopl.h" #include "sound/musicplugin.h" +#include "common/translation.h" #ifdef DEBUG_ADLIB static int tick; @@ -1586,7 +1587,7 @@ void MidiDriver_ADLIB::adlib_note_on(int chan, byte note, int mod) { class AdLibEmuMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "AdLib Emulator"; + return _s("AdLib Emulator"); } const char *getId() const { @@ -1594,7 +1595,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices AdLibEmuMusicPlugin::getDevices() const { @@ -1603,21 +1604,12 @@ MusicDevices AdLibEmuMusicPlugin::getDevices() const { return devices; } -Common::Error AdLibEmuMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error AdLibEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_ADLIB(g_system->getMixer()); return Common::kNoError; } -MidiDriver *MidiDriver_ADLIB_create() { - MidiDriver *mididriver; - - AdLibEmuMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(ADLIB) //REGISTER_PLUGIN_DYNAMIC(ADLIB, PLUGIN_TYPE_MUSIC, AdLibEmuMusicPlugin); //#else diff --git a/sound/softsynth/fluidsynth.cpp b/sound/softsynth/fluidsynth.cpp index c3bd782cc1..fcb4591a20 100644 --- a/sound/softsynth/fluidsynth.cpp +++ b/sound/softsynth/fluidsynth.cpp @@ -230,7 +230,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices FluidSynthMusicPlugin::getDevices() const { @@ -239,21 +239,12 @@ MusicDevices FluidSynthMusicPlugin::getDevices() const { return devices; } -Common::Error FluidSynthMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error FluidSynthMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_FluidSynth(g_system->getMixer()); return Common::kNoError; } -MidiDriver *MidiDriver_FluidSynth_create() { - MidiDriver *mididriver; - - FluidSynthMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(FLUIDSYNTH) //REGISTER_PLUGIN_DYNAMIC(FLUIDSYNTH, PLUGIN_TYPE_MUSIC, FluidSynthMusicPlugin); //#else diff --git a/sound/softsynth/mt32.cpp b/sound/softsynth/mt32.cpp index 612dce06b0..95263a040d 100644 --- a/sound/softsynth/mt32.cpp +++ b/sound/softsynth/mt32.cpp @@ -39,6 +39,7 @@ #include "common/system.h" #include "common/util.h" #include "common/archive.h" +#include "common/translation.h" #include "graphics/fontman.h" #include "graphics/surface.h" @@ -323,7 +324,7 @@ int MidiDriver_MT32::open() { } _initialising = true; - drawMessage(-1, "Initialising MT-32 Emulator"); + drawMessage(-1, _s("Initialising MT-32 Emulator")); if (!_synth->open(prop)) return MERR_DEVICE_NOT_AVAILABLE; _initialising = false; @@ -537,7 +538,7 @@ void MidiDriver_ThreadedMT32::onTimer() { class MT32EmuMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "MT-32 Emulator"; + return _s("MT-32 Emulator"); } const char *getId() const { @@ -545,7 +546,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices MT32EmuMusicPlugin::getDevices() const { @@ -554,23 +555,13 @@ MusicDevices MT32EmuMusicPlugin::getDevices() const { return devices; } -Common::Error MT32EmuMusicPlugin::createInstance(MidiDriver **mididriver) const { - *mididriver = new MidiDriver_MT32(g_system->getMixer()); - - return Common::kNoError; -} - -MidiDriver *MidiDriver_MT32_create() { - // HACK: It will stay here until engine plugin loader overhaul +Common::Error MT32EmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { if (ConfMan.hasKey("extrapath")) SearchMan.addDirectory("extrapath", ConfMan.get("extrapath")); - MidiDriver *mididriver; - - MT32EmuMusicPlugin p; - p.createInstance(&mididriver); + *mididriver = new MidiDriver_MT32(g_system->getMixer()); - return mididriver; + return Common::kNoError; } //#if PLUGIN_ENABLED_DYNAMIC(MT32) diff --git a/sound/softsynth/ym2612.cpp b/sound/softsynth/ym2612.cpp index e337bc4ab9..08331c6244 100644 --- a/sound/softsynth/ym2612.cpp +++ b/sound/softsynth/ym2612.cpp @@ -27,6 +27,7 @@ #include "sound/softsynth/ym2612.h" #include "common/util.h" #include "sound/musicplugin.h" +#include "common/translation.h" //////////////////////////////////////// // @@ -758,7 +759,7 @@ void MidiDriver_YM2612::removeLookupTables() { class TownsEmuMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "FM Towns Emulator"; + return _s("FM Towns Emulator"); } const char *getId() const { @@ -766,7 +767,7 @@ public: } MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices TownsEmuMusicPlugin::getDevices() const { @@ -775,21 +776,12 @@ MusicDevices TownsEmuMusicPlugin::getDevices() const { return devices; } -Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver) const { +Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_YM2612(g_system->getMixer()); return Common::kNoError; } -MidiDriver *MidiDriver_YM2612_create() { - MidiDriver *mididriver; - - TownsEmuMusicPlugin p; - p.createInstance(&mididriver); - - return mididriver; -} - //#if PLUGIN_ENABLED_DYNAMIC(TOWNS) //REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin); //#else |