diff options
Diffstat (limited to 'backends/midi')
-rw-r--r-- | backends/midi/alsa.cpp | 321 | ||||
-rw-r--r-- | backends/midi/camd.cpp | 13 | ||||
-rw-r--r-- | backends/midi/coreaudio.cpp | 13 | ||||
-rw-r--r-- | backends/midi/coremidi.cpp | 13 | ||||
-rw-r--r-- | backends/midi/dmedia.cpp | 13 | ||||
-rw-r--r-- | backends/midi/seq.cpp | 17 | ||||
-rw-r--r-- | backends/midi/stmidi.cpp | 14 | ||||
-rw-r--r-- | backends/midi/timidity.cpp | 13 | ||||
-rw-r--r-- | backends/midi/windows.cpp | 51 | ||||
-rw-r--r-- | backends/midi/ypa1.cpp | 150 | ||||
-rw-r--r-- | backends/midi/zodiac.cpp | 170 |
11 files changed, 276 insertions, 512 deletions
diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index c38537248c..4f73d7384b 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -24,7 +24,7 @@ #include "common/scummsys.h" -#if defined(UNIX) && defined(USE_ALSA) +#if defined(USE_ALSA) #include "common/config-manager.h" #include "common/util.h" @@ -48,6 +48,17 @@ #define my_snd_seq_open(seqp) snd_seq_open(seqp, SND_SEQ_OPEN) #endif +#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) + +static int check_permission(snd_seq_port_info_t *pinfo) +{ + if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) { + if (!(snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT)) + return 1; + } + return 0; +} + /* * parse address string */ @@ -56,7 +67,7 @@ class MidiDriver_ALSA:public MidiDriver_MPU401 { public: - MidiDriver_ALSA(); + MidiDriver_ALSA(int client, int port); int open(); void close(); void send(uint32 b); @@ -69,34 +80,19 @@ private: snd_seq_t *seq_handle; int seq_client, seq_port; int my_client, my_port; - static int parse_addr(const char *arg, int *client, int *port); }; -MidiDriver_ALSA::MidiDriver_ALSA() - : _isOpen(false), seq_handle(0), seq_client(0), seq_port(0), my_client(0), my_port(0) +MidiDriver_ALSA::MidiDriver_ALSA(int client, int port) + : _isOpen(false), seq_handle(0), seq_client(client), seq_port(port), my_client(0), my_port(0) { memset(&ev, 0, sizeof(ev)); } int MidiDriver_ALSA::open() { - const char *var = NULL; - if (_isOpen) return MERR_ALREADY_OPEN; _isOpen = true; - var = getenv("SCUMMVM_PORT"); - if (!var && ConfMan.hasKey("alsa_port")) { - var = ConfMan.get("alsa_port").c_str(); - } - - if (var) { - if (parse_addr(var, &seq_client, &seq_port) < 0) { - error("Invalid port %s", var); - return -1; - } - } - if (my_snd_seq_open(&seq_handle) < 0) { error("Can't open sequencer"); return -1; @@ -108,9 +104,14 @@ int MidiDriver_ALSA::open() { } snd_seq_set_client_group(seq_handle, "input"); - my_port = snd_seq_create_simple_port(seq_handle, "SCUMMVM port 0", - SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE | - SND_SEQ_PORT_CAP_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC); + // According to http://www.alsa-project.org/~tiwai/alsa-subs.html + // you can set read or write capabilities to allow other clients to + // read or write the port. I don't think we need that, unless maybe + // to be able to record the sound, but I can't get that to work even + // with those capabilities. + + my_port = snd_seq_create_simple_port(seq_handle, "SCUMMVM port 0", 0, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if (my_port < 0) { snd_seq_close(seq_handle); @@ -118,29 +119,45 @@ int MidiDriver_ALSA::open() { return -1; } - if (var) { - if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { - // subscribe to MIDI port - if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { - error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port); + if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { + // Subscribe to MIDI port. Prefer one that doesn't already have + // any connections, unless we've forced a port number already. + if (seq_port == -1) { + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + + snd_seq_client_info_alloca(&cinfo); + snd_seq_port_info_alloca(&pinfo); + + snd_seq_get_any_client_info(seq_handle, seq_client, cinfo); + + int first_port = -1; + int found_port = -1; + + snd_seq_port_info_set_client(pinfo, seq_client); + snd_seq_port_info_set_port(pinfo, -1); + while (found_port == -1 && snd_seq_query_next_port(seq_handle, pinfo) >= 0) { + if (check_permission(pinfo)) { + if (first_port == -1) + first_port = snd_seq_port_info_get_port(pinfo); + if (found_port == -1 && snd_seq_port_info_get_write_use(pinfo) == 0) + found_port = snd_seq_port_info_get_port(pinfo); + } + } + + if (found_port == -1) { + // Should we abort here? For now, use the first + // available port. + seq_port = first_port; + warning("MidiDriver_ALSA: All ports on client %d (%s) are already in use", seq_client, snd_seq_client_info_get_name(cinfo)); + } else { + seq_port = found_port; } - } - } else { - int defaultPorts[] = { - 65, 0, - 17, 0 - }; - int i; - - for (i = 0; i < ARRAYSIZE(defaultPorts); i += 2) { - seq_client = defaultPorts[i]; - seq_port = defaultPorts[i + 1]; - if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) >= 0) - break; } - if (i >= ARRAYSIZE(defaultPorts)) - error("Can't subscribe to MIDI port (65:0) or (17:0)"); + if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { + error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port); + } } printf("Connected to Alsa sequencer client [%d:%d]\n", seq_client, seq_port); @@ -150,10 +167,13 @@ int MidiDriver_ALSA::open() { } void MidiDriver_ALSA::close() { - _isOpen = false; - MidiDriver_MPU401::close(); - if (seq_handle) - snd_seq_close(seq_handle); + if (_isOpen) { + _isOpen = false; + MidiDriver_MPU401::close(); + if (seq_handle) + snd_seq_close(seq_handle); + } else + warning("MidiDriver_ALSA: Closing the driver before opening it"); } void MidiDriver_ALSA::send(uint32 b) { @@ -227,24 +247,6 @@ void MidiDriver_ALSA::sysEx(const byte *msg, uint16 length) { send_event(1); } -int MidiDriver_ALSA::parse_addr(const char *arg, int *client, int *port) { - const char *p; - - if (isdigit(*arg)) { - if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) - return -1; - *client = atoi(arg); - *port = atoi(p + 1); - } else { - if (*arg == 's' || *arg == 'S') { - *client = SND_SEQ_ADDRESS_SUBSCRIBERS; - *port = 0; - } else - return -1; - } - return 0; -} - void MidiDriver_ALSA::send_event(int do_flush) { snd_seq_ev_set_direct(&ev); snd_seq_ev_set_source(&ev, my_port); @@ -258,6 +260,37 @@ void MidiDriver_ALSA::send_event(int do_flush) { // Plugin interface +class AlsaDevice { +public: + AlsaDevice(Common::String name, MusicType mt, int client); + Common::String getName(); + MusicType getType(); + int getClient(); + +private: + Common::String _name; + MusicType _type; + int _client; +}; + +typedef Common::List<AlsaDevice> AlsaDevices; + +AlsaDevice::AlsaDevice(Common::String name, MusicType mt, int client) + : _name(name), _type(mt), _client(client) { +} + +Common::String AlsaDevice::getName() { + return _name; +} + +MusicType AlsaDevice::getType() { + return _type; +} + +int AlsaDevice::getClient() { + return _client; +} + class AlsaMusicPlugin : public MusicPluginObject { public: const char *getName() const { @@ -268,26 +301,18 @@ public: return "alsa"; } + AlsaDevices getAlsaDevices() const; MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; -}; - -#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; -static int check_permission(snd_seq_port_info_t *pinfo) -{ - if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) { - if (!(snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT)) - return 1; - } - return 0; -} - -MusicDevices AlsaMusicPlugin::getDevices() const { - MusicDevices devices; +private: + static int parse_addr(const char *arg, int *client, int *port); +}; - snd_seq_t *seq; - if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) +AlsaDevices AlsaMusicPlugin::getAlsaDevices() const { + AlsaDevices devices; + snd_seq_t *seq_handle; + if (my_snd_seq_open(&seq_handle) < 0) return devices; // can't open sequencer snd_seq_client_info_t *cinfo; @@ -295,39 +320,145 @@ MusicDevices AlsaMusicPlugin::getDevices() const { snd_seq_port_info_t *pinfo; snd_seq_port_info_alloca(&pinfo); snd_seq_client_info_set_client(cinfo, -1); - while (snd_seq_query_next_client(seq, cinfo) >= 0) { + while (snd_seq_query_next_client(seq_handle, cinfo) >= 0) { bool found_valid_port = false; /* reset query info */ snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); snd_seq_port_info_set_port(pinfo, -1); - while (!found_valid_port && snd_seq_query_next_port(seq, pinfo) >= 0) { + while (!found_valid_port && snd_seq_query_next_port(seq_handle, pinfo) >= 0) { if (check_permission(pinfo)) { found_valid_port = true; - // TODO: Return a different music type depending on the configuration - devices.push_back(MusicDevice(this, snd_seq_client_info_get_name(cinfo), MT_GM)); - //snd_seq_client_info_get_client(cinfo) : snd_seq_port_info_get_port(pinfo) + + const char *name = snd_seq_client_info_get_name(cinfo); + // TODO: Can we figure out the appropriate music type? + MusicType type = MT_GM; + int client = snd_seq_client_info_get_client(cinfo); + devices.push_back(AlsaDevice(name, type, client)); } } } - snd_seq_close(seq); + snd_seq_close(seq_handle); return devices; } -Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver) const { - *mididriver = new MidiDriver_ALSA(); +MusicDevices AlsaMusicPlugin::getDevices() const { + MusicDevices devices; + AlsaDevices::iterator d; - return Common::kNoError; + AlsaDevices alsaDevices = getAlsaDevices(); + + // Since the default behaviour is to use the first device in the list, + // try to put something sensible there. We used to have 17:0 and 65:0 + // as defaults. + + for (d = alsaDevices.begin(); d != alsaDevices.end();) { + const int client = d->getClient(); + + if (client == 17 || client == 65) { + devices.push_back(MusicDevice(this, d->getName(), d->getType())); + d = alsaDevices.erase(d); + } else { + ++d; + } + } + + // 128:0 is probably TiMidity, or something like that, so that's + // probably a good second choice. + + for (d = alsaDevices.begin(); d != alsaDevices.end();) { + if (d->getClient() == 128) { + devices.push_back(MusicDevice(this, d->getName(), d->getType())); + d = alsaDevices.erase(d); + } else { + ++d; + } + } + + // Add the remaining devices in the order they were found. + + for (d = alsaDevices.begin(); d != alsaDevices.end(); ++d) + devices.push_back(MusicDevice(this, d->getName(), d->getType())); + + return devices; } -MidiDriver *MidiDriver_ALSA_create() { - MidiDriver *mididriver; +Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle dev) const { + bool found = false; + int seq_client, seq_port; + + const char *var = NULL; + + // TODO: Upgrade from old alsa_port setting. This probably isn't the + // right place to do that, though. - AlsaMusicPlugin p; - p.createInstance(&mididriver); + if (ConfMan.hasKey("alsa_port")) { + warning("AlsaMusicPlugin: Found old 'alsa_port' setting, which will be ignored"); + } + + // The SCUMMVM_PORT environment variable can still be used to override + // any config setting. - return mididriver; + var = getenv("SCUMMVM_PORT"); + if (var) { + warning("AlsaMusicPlugin: SCUMMVM_PORT environment variable overrides config settings"); + if (parse_addr(var, &seq_client, &seq_port) >= 0) { + found = true; + } else { + warning("AlsaMusicPlugin: Invalid port %s, using config settings instead", var); + } + } + + // Try to match the setting to an available ALSA device. + + if (!found && dev) { + AlsaDevices alsaDevices = getAlsaDevices(); + + for (AlsaDevices::iterator d = alsaDevices.begin(); d != alsaDevices.end(); ++d) { + MusicDevice device(this, d->getName(), d->getType()); + + if (device.getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) { + found = true; + seq_client = d->getClient(); + seq_port = -1; + break; + } + } + } + + // Still nothing? Try a sensible default. + + if (!found) { + // TODO: What's a sensible default anyway? And exactly when do + // we get to this case? + + warning("AlsaMusicPlugin: Using 17:0 as default ALSA port"); + seq_client = 17; + seq_port = 0; + } + + *mididriver = new MidiDriver_ALSA(seq_client, seq_port); + + return Common::kNoError; +} + +int AlsaMusicPlugin::parse_addr(const char *arg, int *client, int *port) { + const char *p; + + if (isdigit(*arg)) { + if ((p = strpbrk(arg, ADDR_DELIM)) == NULL) + return -1; + *client = atoi(arg); + *port = atoi(p + 1); + } else { + if (*arg == 's' || *arg == 'S') { + *client = SND_SEQ_ADDRESS_SUBSCRIBERS; + *port = 0; + } else + return -1; + } + return 0; } //#if PLUGIN_ENABLED_DYNAMIC(ALSA) 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..e3d2c35b39 100644 --- a/backends/midi/seq.cpp +++ b/backends/midi/seq.cpp @@ -28,7 +28,9 @@ * both the QuickTime support and (vkeybd http://www.alsa-project.org/~iwai/alsa.html) */ -#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__) +#include "common/scummsys.h" + +#if defined(USE_SEQ_MIDI) #include "common/util.h" #include "sound/musicplugin.h" @@ -184,7 +186,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 +197,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..da44c40978 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -24,12 +24,15 @@ #if defined(WIN32) && !defined(_WIN32_WCE) +#define WIN32_LEAN_AND_MEAN #include <windows.h> // winnt.h defines ARRAYSIZE, but we want our own one... #undef ARRAYSIZE #include "sound/musicplugin.h" #include "sound/mpu401.h" +#include "common/config-manager.h" +#include "common/translation.h" #include <mmsystem.h> @@ -46,11 +49,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 +66,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); @@ -150,7 +154,7 @@ void MidiDriver_WIN::check_error(MMRESULT result) { class WindowsMusicPlugin : public MusicPluginObject { public: const char *getName() const { - return "Windows MIDI"; + return _s("Windows MIDI"); } const char *getId() const { @@ -158,32 +162,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 deleted file mode 100644 index fe65d02c10..0000000000 --- a/backends/midi/ypa1.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" - -#include "Pa1Lib.h" - -class MidiDriver_YamahaPa1:public MidiDriver_MPU401 { -public: - MidiDriver_YamahaPa1(); - int open(); - void close(); - void send(uint32 b); - -private: - UInt8 _midiHandle; - Boolean _isOpen; - }; - -MidiDriver_YamahaPa1::MidiDriver_YamahaPa1() { - _isOpen = false; - _midiHandle = 0; -} - -int MidiDriver_YamahaPa1::open() { - if (!(_isOpen = Pa1Lib_midiOpen(NULL, &_midiHandle))) - return MERR_DEVICE_NOT_AVAILABLE; - - return 0; -} - -void MidiDriver_YamahaPa1::close() { - if (_isOpen) { - _isOpen = false; - MidiDriver_MPU401::close(); - for (UInt8 channel = 0; channel < 16; channel++) { - Pa1Lib_midiControlChange(_midiHandle, channel, 120,0); // all sound off - Pa1Lib_midiControlChange(_midiHandle, channel, 121,0); // reset all controller - Pa1Lib_midiControlChange(_midiHandle, channel, 123, 0); // all notes off - } - Pa1Lib_midiClose(_midiHandle); - } -} - -void MidiDriver_YamahaPa1::send(uint32 b) { - if (!_isOpen) - return; - - UInt8 midiCmd[4]; - UInt8 chanID,mdCmd; - - midiCmd[3] = (b & 0xFF000000) >> 24; - midiCmd[2] = (b & 0x00FF0000) >> 16; - midiCmd[1] = (b & 0x0000FF00) >> 8; - midiCmd[0] = (b & 0x000000FF); - - chanID = (midiCmd[0] & 0x0F) ; - mdCmd = midiCmd[0] & 0xF0; - - switch (mdCmd) { - case 0x80: // note off - Pa1Lib_midiNoteOff(_midiHandle, chanID, midiCmd[1], 0); - break; - - case 0x90: // note on - Pa1Lib_midiNoteOn(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xB0: // control change - Pa1Lib_midiControlChange(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xC0: // progam change - Pa1Lib_midiProgramChange(_midiHandle, chanID, midiCmd[1]); - break; - - case 0xE0: // pitchBend - Pa1Lib_midiPitchBend(_midiHandle, chanID, (short)(midiCmd[1] | (midiCmd[2] << 8))); - break; - } -} - - -// Plugin interface - -class YamahaPa1MusicPlugin : public MusicPluginObject { -public: - const char *getName() const { - return "Yamaha Pa1"; - } - - const char *getId() const { - return "ypa1"; - } - - MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; -}; - -MusicDevices YamahaPa1MusicPlugin::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)); - return devices; -} - -Common::Error YamahaPa1MusicPlugin::createInstance(MidiDriver **mididriver) 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 - REGISTER_PLUGIN_STATIC(YPA1, PLUGIN_TYPE_MUSIC, YamahaPa1MusicPlugin); -//#endif diff --git a/backends/midi/zodiac.cpp b/backends/midi/zodiac.cpp deleted file mode 100644 index b9cb46912a..0000000000 --- a/backends/midi/zodiac.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" - -#ifndef DISABLE_TAPWAVE - -#include <tapwave.h> - - -class MidiDriver_Zodiac:public MidiDriver_MPU401 { -public: - MidiDriver_Zodiac(); - int open(); - void close(); - void send(uint32 b); - void sysEx(const byte *msg, uint16 length); - -private: - TwMidiHandle _midiHandle; - Boolean _isOpen; - Int32 _oldVol; - }; - -MidiDriver_Zodiac::MidiDriver_Zodiac() { - _isOpen = false; - _midiHandle = 0; -} - -int MidiDriver_Zodiac::open() { - Err e; - - if (e = TwMidiOpen(&_midiHandle)) - return MERR_DEVICE_NOT_AVAILABLE; - - TwMidiGetMasterVolume(&_oldVol); - TwMidiSetMasterVolume(twMidiMaxVolume); // TODO : set volume based on gVars - - _isOpen = true; - return 0; -} - -void MidiDriver_Zodiac::close() { - if (_isOpen) { - _isOpen = false; - MidiDriver_MPU401::close(); - - TwMidiSetMasterVolume(_oldVol); - TwMidiClose(_midiHandle); - } -} - -void MidiDriver_Zodiac::send(uint32 b) { - if (!_isOpen) - return; - - UInt8 midiCmd[4]; - UInt8 chanID,mdCmd; - - midiCmd[3] = (b & 0xFF000000) >> 24; - midiCmd[2] = (b & 0x00FF0000) >> 16; - midiCmd[1] = (b & 0x0000FF00) >> 8; - midiCmd[0] = (b & 0x000000FF); - - chanID = (midiCmd[0] & 0x0F) ; - mdCmd = midiCmd[0] & 0xF0; - - switch (mdCmd) { - case 0x80: // note off - TwMidiNoteOff(_midiHandle, chanID, midiCmd[1], 0); - break; - - case 0x90: // note on - TwMidiNoteOn(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xB0: // control change - TwMidiControlChange(_midiHandle, chanID, midiCmd[1], midiCmd[2]); - break; - - case 0xC0: // progam change - TwMidiProgramChange(_midiHandle, chanID, midiCmd[1]); - break; - - case 0xE0: // pitchBend - TwMidiPitchBend(_midiHandle, chanID, (short)(midiCmd[1] | (midiCmd[2] << 8))); - break; - } -} - -void MidiDriver_Zodiac::sysEx(const byte *msg, uint16 length) { - unsigned char buf[266]; - - buf[0] = 0xF0; - memcpy(buf + 1, msg, length); - buf[length + 1] = 0xF7; - - TwMidiSysEx(_midiHandle, 0, (byte *)buf, length + 2); -} - - -// Plugin interface - -class ZodiacMusicPlugin : public MusicPluginObject { -public: - const char *getName() const { - return "Tapwave Zodiac"; - } - - const char *getId() const { - return "zodiac"; - } - - MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver) const; -}; - -MusicDevices ZodiacMusicPlugin::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)); - return devices; -} - -Common::Error ZodiacMusicPlugin::createInstance(MidiDriver **mididriver) 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 - REGISTER_PLUGIN_STATIC(ZODIAC, PLUGIN_TYPE_MUSIC, ZodiacMusicPlugin); -//#endif - -#endif |