diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index ec0a145a..1ae12e70 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,5 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h +libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h \ + midi.cpp midi_win32.h midi_oss.h diff --git a/src/gui/midi.cpp b/src/gui/midi.cpp new file mode 100644 index 00000000..7360faa5 --- /dev/null +++ b/src/gui/midi.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "dosbox.h" +#include "setup.h" + +Bit8u MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,1, 1,0,1,1, 1,0,1,1 // 0xf0 +}; + + +#if defined (WIN32) + +#include "midi_win32.h" + +#elif defined (UNIX) && !defined(__BEOS__) + +#include "midi_oss.h" + +#else /* Fall back to no device playing */ + +static void MIDI_PlayMsg(Bit32u msg) {} +static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) {}; +static bool MIDI_StartUp(void) { return false;} + +#endif + + +static struct { + Bitu status; + Bitu cmd_len; + Bitu cmd_pos; + + Bit32u cmd_msg; + Bit8u data[4]; + struct { + Bit8u buf[256]; + Bitu used; + bool active; + } sysex; + bool available; +} midi; + + +void MIDI_RawOutByte(Bit8u data) { + /* Test for a new status byte */ + if (midi.sysex.active && !(data&0x80)) { + if (midi.sysex.used<256) midi.sysex.buf[midi.sysex.used++]=data; + return; + } else if (data&0x80) { + if (midi.sysex.active) { + /* Play a sysex message */ + midi.sysex.buf[midi.sysex.used++]=0xf7; + MIDI_PlaySysex(midi.sysex.buf,midi.sysex.used); + LOG(0,"Sysex message size %d",midi.sysex.used); + midi.sysex.active=false; + if (data==0xf7) return; + } + midi.status=data; + midi.cmd_pos=0; + midi.cmd_msg=0; + if (midi.status==0xf0) { + midi.sysex.active=true; + midi.sysex.buf[0]=0xf0; + midi.sysex.used=1; + return; + } + midi.cmd_len=MIDI_evt_len[data]; + } + midi.cmd_msg|=data << (8 * midi.cmd_pos); + midi.cmd_pos++; + if (midi.cmd_pos >= midi.cmd_len) { + MIDI_PlayMsg(midi.cmd_msg); + midi.cmd_msg=midi.status; + midi.cmd_pos=1; + } +} + +bool MIDI_Available(void) { + return midi.available; +} + + +void MIDI_Init(Section * sect) { + midi.available=MIDI_StartUp(); +} + diff --git a/src/gui/midi_oss.h b/src/gui/midi_oss.h new file mode 100644 index 00000000..2141392d --- /dev/null +++ b/src/gui/midi_oss.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +static int m_device; + +#define SEQ_MIDIPUTC 5 + +static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { + Bit8u buf[1024];Bitu pos=0; + for (;len>0;len--) { + buf[pos++] = SEQ_MIDIPUTC; + buf[pos++] = *sysex++; + buf[pos++] = 0; //Device 0? + buf[pos++] = 0; + } + write(m_device,buf,pos); +} + +static void MIDI_PlayMsg(Bit32u msg) { + Bit8u buf[128];Bitu pos=0; + + Bitu len=MIDI_evt_len[msg & 0xff]; + for (;len>0;len--) { + buf[pos++] = SEQ_MIDIPUTC; + buf[pos++] = msg & 0xff; + buf[pos++] = 0; //Device 0? + buf[pos++] = 0; + msg >>=8; + } + write(m_device,buf,pos); +} + +static void MIDI_ShutDown(void) { + if (m_device>0) close(m_device); +} + +static bool MIDI_StartUp(void) { + m_device=open("/dev/midi", O_WRONLY, 0); + if (m_device<0) return false; + return true; +} + + diff --git a/src/gui/midi_win32.h b/src/gui/midi_win32.h new file mode 100644 index 00000000..5501e53c --- /dev/null +++ b/src/gui/midi_win32.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2002-2003 The DOSBox Team + * + * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +static HMIDIOUT m_out; +static MIDIHDR m_hdr; +static HANDLE m_event; + +static Bit8u m_msg[300]; + +static void MIDI_PlaySysex(Bit8u * sysex,Bitu len) { + + if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) { + LOG(LOG_MISC|LOG_ERROR,"Can't send midi message"); + return; + } + midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr)); + memcpy (&m_msg, sysex, len); + + m_hdr.lpData = (char *) m_msg; + m_hdr.dwBufferLength = len ; + m_hdr.dwBytesRecorded = len ; + m_hdr.dwUser = 0; + + MMRESULT result = midiOutPrepareHeader (m_out, &m_hdr, sizeof (m_hdr)); + if (result != MMSYSERR_NOERROR) return; + ResetEvent (m_event); + result = midiOutLongMsg (m_out,&m_hdr,sizeof(m_hdr)); + if (result != MMSYSERR_NOERROR) { + SetEvent (m_event); + return; + } +} + +static void MIDI_PlayMsg(Bit32u msg) { + MMRESULT ret=midiOutShortMsg(m_out, msg); +} + + + +static bool MIDI_StartUp(void) { + m_event = CreateEvent (NULL, true, true, NULL); + MMRESULT res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT); + if (res != MMSYSERR_NOERROR) return false; + return true; +} + + +