ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

camd.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Disable symbol overrides so that we can use system headers.
00024 #define FORBIDDEN_SYMBOL_ALLOW_ALL
00025 
00026 #include "common/scummsys.h"
00027 
00028 #if defined(__amigaos4__)
00029 
00030 #include "common/textconsole.h"
00031 #include "common/error.h"
00032 #include "common/endian.h"
00033 #include "common/util.h"
00034 #include "common/str.h"
00035 #include "audio/musicplugin.h"
00036 #include "audio/mpu401.h"
00037 
00038 #include <proto/camd.h>
00039 #include <proto/exec.h>
00040 #include <proto/dos.h>
00041 
00042 /*
00043  * CAMD sequencer driver
00044  * Mostly cut'n'pasted from FreeSCI by Christoph Reichenbach
00045  */
00046 
00047 class MidiDriver_CAMD : public MidiDriver_MPU401 {
00048 public:
00049     MidiDriver_CAMD();
00050     int open();
00051     bool isOpen() const { return _isOpen; }
00052     void close();
00053     void send(uint32 b);
00054     void sysEx(const byte *msg, uint16 length);
00055 
00056 private:
00057     bool _isOpen;
00058     struct Library *_CamdBase;
00059     struct CamdIFace *_ICamd;
00060     struct MidiLink *_midi_link;
00061     char _outport[128];
00062 
00063     char *getDevice();
00064     void closeAll();
00065 };
00066 
00067 MidiDriver_CAMD::MidiDriver_CAMD()
00068     : _isOpen(false), _CamdBase(NULL), _ICamd(NULL), _midi_link(NULL) {
00069 }
00070 
00071 int MidiDriver_CAMD::open() {
00072     if (_isOpen)
00073         return MERR_ALREADY_OPEN;
00074 
00075     _CamdBase = IExec->OpenLibrary("camd.library", 36L);
00076     if (!_CamdBase) {
00077         error("Could not open 'camd.library'");
00078         return -1;
00079     }
00080 
00081     _ICamd = (struct CamdIFace *) IExec->GetInterface(_CamdBase, "main", 1, NULL);
00082     if (!_ICamd) {
00083         closeAll();
00084         error("Error while retrieving CAMD interface");
00085         return -1;
00086     }
00087 
00088     struct MidiNode *midi_node;
00089     midi_node = _ICamd->CreateMidi(MIDI_MsgQueue, 0L, MIDI_SysExSize, 4096L, MIDI_Name, "residualvm", TAG_END);
00090     if (!midi_node) {
00091         closeAll();
00092         error("Could not create CAMD MIDI node");
00093         return -1;
00094     }
00095 
00096     char *devicename = getDevice();
00097     if (!devicename) {
00098         closeAll();
00099         error("Could not find an output device");
00100         return MERR_DEVICE_NOT_AVAILABLE;
00101     }
00102 
00103     _midi_link = _ICamd->AddMidiLink(midi_node, MLTYPE_Sender, MLINK_Location, devicename, TAG_END);
00104     if (!_midi_link) {
00105         closeAll();
00106         error("Could not create CAMD MIDI link to '%s'", devicename);
00107         return MERR_CANNOT_CONNECT;
00108     }
00109 
00110     _isOpen = true;
00111     return 0;
00112 }
00113 
00114 void MidiDriver_CAMD::close() {
00115     MidiDriver_MPU401::close();
00116     closeAll();
00117 }
00118 
00119 void MidiDriver_CAMD::send(uint32 b) {
00120     if (!_isOpen) {
00121         warning("MidiDriver_CAMD: Got event while not open");
00122         return;
00123     }
00124 
00125     ULONG data = READ_LE_UINT32(&b);
00126     _ICamd->PutMidi(_midi_link, data);
00127 }
00128 
00129 void MidiDriver_CAMD::sysEx(const byte *msg, uint16 length) {
00130     if (!_isOpen) {
00131         warning("MidiDriver_CAMD: Got SysEx while not open");
00132         return;
00133     }
00134 
00135     unsigned char buf[266];
00136 
00137     assert(length + 2 <= ARRAYSIZE(buf));
00138 
00139     // Add SysEx frame
00140     buf[0] = 0xF0;
00141     memcpy(buf + 1, msg, length);
00142     buf[length + 1] = 0xF7;
00143 
00144     // Send it
00145     _ICamd->PutSysEx(_midi_link, buf);
00146 }
00147 
00148 char *MidiDriver_CAMD::getDevice() {
00149     char *retname = NULL;
00150 
00151     APTR key = _ICamd->LockCAMD(CD_Linkages);
00152     if (key != NULL) {
00153         struct MidiCluster *cluster = _ICamd->NextCluster(NULL);
00154 
00155         while (cluster && !retname) {
00156             // Get the current cluster name
00157             char *dev = cluster->mcl_Node.ln_Name;
00158 
00159             if (strstr(dev, "out") != NULL) {
00160                 // This is an output device, return this
00161                 Common::strlcpy(_outport, dev, sizeof(_outport));
00162                 retname = _outport;
00163             } else {
00164                 // Search the next one
00165                 cluster = _ICamd->NextCluster(cluster);
00166             }
00167         }
00168 
00169         // If the user has a preference outport set, use this instead
00170         if(IDOS->GetVar("DefMidiOut", _outport, 128, 0))
00171             retname = _outport;
00172 
00173         _ICamd->UnlockCAMD(key);
00174     }
00175 
00176     return retname;
00177 }
00178 
00179 void MidiDriver_CAMD::closeAll() {
00180     if (_ICamd)
00181         IExec->DropInterface((struct Interface *)_ICamd);
00182     if (_CamdBase)
00183         IExec->CloseLibrary(_CamdBase);
00184 
00185     _isOpen = false;
00186 }
00187 
00188 
00189 // Plugin interface
00190 
00191 class CamdMusicPlugin : public MusicPluginObject {
00192 public:
00193     const char *getName() const {
00194         return "CAMD";
00195     }
00196 
00197     const char *getId() const {
00198         return "camd";
00199     }
00200 
00201     MusicDevices getDevices() const;
00202     Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
00203 };
00204 
00205 MusicDevices CamdMusicPlugin::getDevices() const {
00206     MusicDevices devices;
00207     // TODO: Return a different music type depending on the configuration
00208     // TODO: List the available devices
00209     devices.push_back(MusicDevice(this, "", MT_GM));
00210     return devices;
00211 }
00212 
00213 Common::Error CamdMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
00214     *mididriver = new MidiDriver_CAMD();
00215 
00216     return Common::kNoError;
00217 }
00218 
00219 //#if PLUGIN_ENABLED_DYNAMIC(CAMD)
00220     //REGISTER_PLUGIN_DYNAMIC(CAMD, PLUGIN_TYPE_MUSIC, CamdMusicPlugin);
00221 //#else
00222     REGISTER_PLUGIN_STATIC(CAMD, PLUGIN_TYPE_MUSIC, CamdMusicPlugin);
00223 //#endif
00224 
00225 #endif


Generated on Sat Feb 23 2019 05:00:58 for ResidualVM by doxygen 1.7.1
curved edge   curved edge