aboutsummaryrefslogtreecommitdiff
path: root/backends/midi/stmidi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/midi/stmidi.cpp')
-rw-r--r--backends/midi/stmidi.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/backends/midi/stmidi.cpp b/backends/midi/stmidi.cpp
new file mode 100644
index 0000000000..addb23c6bd
--- /dev/null
+++ b/backends/midi/stmidi.cpp
@@ -0,0 +1,155 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * 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.
+ */
+
+/*
+ * Raw MIDI output for the Atari ST line of computers.
+ * Based on the ScummVM SEQ & CoreMIDI drivers.
+ * Atari code by Keith Scroggins
+ * We, unfortunately, could not use the SEQ driver because the /dev/midi under
+ * FreeMiNT (and hence in libc) is considered to be a serial port for machine
+ * access. So, we just use OS calls then to send the data to the MIDI ports
+ * directly. The current implementation is sending 1 byte at a time because
+ * in most cases we are only sending up to 3 bytes, I believe this saves a few
+ * cycles. I might change so sysex messages are sent the other way later.
+ */
+
+#if defined __MINT__
+
+#include <osbind.h>
+#include "sound/mpu401.h"
+#include "common/util.h"
+#include "sound/musicplugin.h"
+
+class MidiDriver_STMIDI : public MidiDriver_MPU401 {
+public:
+ MidiDriver_STMIDI() : _isOpen (false) { }
+ int open();
+ void close();
+ void send(uint32 b);
+ void sysEx(const byte *msg, uint16 length);
+
+private:
+ bool _isOpen;
+};
+
+int MidiDriver_STMIDI::open() {
+ if ((_isOpen) && (!Bcostat(4)))
+ return MERR_ALREADY_OPEN;
+ warning("ST Midi Port Open");
+ _isOpen = true;
+ return 0;
+}
+
+void MidiDriver_STMIDI::close() {
+ MidiDriver_MPU401::close();
+ _isOpen = false;
+}
+
+void MidiDriver_STMIDI::send(uint32 b) {
+
+ byte status_byte = (b & 0x000000FF);
+ byte first_byte = (b & 0x0000FF00) >> 8;
+ byte second_byte = (b & 0x00FF0000) >> 16;
+
+// warning("ST MIDI Packet sent");
+
+ switch (b & 0xF0) {
+ case 0x80: // Note Off
+ case 0x90: // Note On
+ case 0xA0: // Polyphonic Key Pressure
+ case 0xB0: // Controller
+ case 0xE0: // Pitch Bend
+ Bconout(3, status_byte);
+ Bconout(3, first_byte);
+ Bconout(3, second_byte);
+ break;
+ case 0xC0: // Program Change
+ case 0xD0: // Aftertouch
+ Bconout(3, status_byte);
+ Bconout(3, first_byte);
+ break;
+ default:
+ fprintf(stderr, "Unknown : %08x\n", (int)b);
+ break;
+ }
+}
+
+void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) {
+ if (length > 254) {
+ warning ("Cannot send SysEx block - data too large");
+ return;
+ }
+
+ const byte *chr = msg;
+ warning("Sending SysEx Message");
+
+ Bconout(3, '0xF0');
+ for (; length; --length, ++chr) {
+ Bconout(3,((unsigned char) *chr & 0x7F));
+ }
+ Bconout(3, '0xF7');
+}
+
+// Plugin interface
+
+class StMidiMusicPlugin : public MusicPluginObject {
+public:
+ const char *getName() const {
+ return "STMIDI";
+ }
+
+ const char *getId() const {
+ return "stmidi";
+ }
+
+ MusicDevices getDevices() const;
+ PluginError createInstance(Audio::Mixer *mixer, MidiDriver **mididriver)
+ const;
+};
+
+MusicDevices StMidiMusicPlugin::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;
+}
+
+PluginError StMidiMusicPlugin::createInstance(Audio::Mixer *mixer, MidiDriver **mididriver) const {
+ *mididriver = new MidiDriver_STMIDI();
+
+ return kNoError;
+}
+
+MidiDriver *MidiDriver_STMIDI_create(Audio::Mixer *mixer) {
+ MidiDriver *mididriver;
+
+ StMidiMusicPlugin p;
+ p.createInstance(mixer, &mididriver);
+
+ return mididriver;
+}
+
+//#if PLUGIN_ENABLED_DYNAMIC(STMIDI)
+ //REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin);
+//#else
+ REGISTER_PLUGIN_STATIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin);
+//#endif
+
+#endif