diff options
| author | Eero Tamminen <oak@helsinkinet.fi> | 2017-11-05 17:40:05 (GMT) |
|---|---|---|
| committer | Eero Tamminen <oak@helsinkinet.fi> | 2017-11-05 17:40:05 (GMT) |
| commit | 7eea8eafd7553234502183f6b14b66d9f0d5e164 (patch) | |
| tree | f34705fe161fb40d8c266f0f50f3a4e9c517b82f | |
| parent | 5b22d05c4f5be0ab9298011d7fd9f9652a824192 (diff) | |
| download | hatari-7eea8eafd7553234502183f6b14b66d9f0d5e164.zip hatari-7eea8eafd7553234502183f6b14b66d9f0d5e164.tar.gz | |
Optional PortMidi library support from Jari Kleimola
With few fixes + command line option from Eero.
| -rw-r--r-- | src/change.c | 11 | ||||
| -rw-r--r-- | src/configuration.c | 4 | ||||
| -rw-r--r-- | src/includes/configuration.h | 2 | ||||
| -rw-r--r-- | src/includes/midi.h | 3 | ||||
| -rw-r--r-- | src/midi.c | 568 | ||||
| -rw-r--r-- | src/options.c | 17 |
6 files changed, 537 insertions, 68 deletions
diff --git a/src/change.c b/src/change.c index 2d2e954..fff440e 100644 --- a/src/change.c +++ b/src/change.c @@ -332,9 +332,14 @@ void Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *ch /* Did change MIDI settings? */ if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi - || ((strcmp(changed->Midi.sMidiOutFileName, current->Midi.sMidiOutFileName) - || strcmp(changed->Midi.sMidiInFileName, current->Midi.sMidiInFileName)) - && changed->Midi.bEnableMidi)) +#ifdef HAVE_PORTMIDI + || strcmp(changed->Midi.sMidiOutPortName, current->Midi.sMidiOutPortName) + || strcmp(changed->Midi.sMidiInPortName, current->Midi.sMidiInPortName) +#else + || strcmp(changed->Midi.sMidiOutFileName, current->Midi.sMidiOutFileName) + || strcmp(changed->Midi.sMidiInFileName, current->Midi.sMidiInFileName) +#endif + ) { Dprintf("- midi>\n"); Midi_UnInit(); diff --git a/src/configuration.c b/src/configuration.c index ca91311..332acb7 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -517,6 +517,8 @@ static const struct Config_Tag configs_Midi[] = { "bEnableMidi", Bool_Tag, &ConfigureParams.Midi.bEnableMidi }, { "sMidiInFileName", String_Tag, ConfigureParams.Midi.sMidiInFileName }, { "sMidiOutFileName", String_Tag, ConfigureParams.Midi.sMidiOutFileName }, + { "sMidiInPortName", String_Tag, ConfigureParams.Midi.sMidiInPortName }, + { "sMidiOutPortName", String_Tag, ConfigureParams.Midi.sMidiOutPortName }, { NULL , Error_Tag, NULL } }; @@ -730,6 +732,8 @@ void Configuration_SetDefault(void) ConfigureParams.Midi.bEnableMidi = false; strcpy(ConfigureParams.Midi.sMidiInFileName, "/dev/snd/midiC1D0"); strcpy(ConfigureParams.Midi.sMidiOutFileName, "/dev/snd/midiC1D0"); + strcpy(ConfigureParams.Midi.sMidiInPortName, "Off"); + strcpy(ConfigureParams.Midi.sMidiOutPortName, "Off"); /* Set defaults for Screen */ ConfigureParams.Screen.bFullScreen = false; diff --git a/src/includes/configuration.h b/src/includes/configuration.h index 190166f..6308d19 100644 --- a/src/includes/configuration.h +++ b/src/includes/configuration.h @@ -295,6 +295,8 @@ typedef struct bool bEnableMidi; char sMidiInFileName[FILENAME_MAX]; char sMidiOutFileName[FILENAME_MAX]; + char sMidiInPortName[FILENAME_MAX]; + char sMidiOutPortName[FILENAME_MAX]; } CNF_MIDI; diff --git a/src/includes/midi.h b/src/includes/midi.h index 5d69a46..e9f776e 100644 --- a/src/includes/midi.h +++ b/src/includes/midi.h @@ -19,4 +19,7 @@ extern void Midi_Control_WriteByte(void); extern void Midi_Data_WriteByte(void); extern void Midi_InterruptHandler_Update(void); +extern const char* Midi_Host_GetPortName(int index, bool forInput); +extern int Midi_Host_GetPortIndex(const char* portName, bool forInput); + #endif @@ -53,8 +53,6 @@ const char Midi_fileid[] = "Hatari midi.c : " __DATE__ " " __TIME__; #define MIDI_TRANSFER_BYTE_CYCLE (MIDI_TRANSFER_BIT_CYCLE * 10) #endif -static FILE *pMidiFhIn = NULL; /* File handle used for Midi input */ -static FILE *pMidiFhOut = NULL; /* File handle used for Midi output */ static Uint8 MidiControlRegister; static Uint8 MidiStatusRegister; static Uint8 nRxDataByte; @@ -63,42 +61,43 @@ static Uint64 TDR_Empty_Time; /* Time when TDR will be empty after a write to f static Uint64 TSR_Complete_Time; /* Time when TSR will be completely transferred */ +/* +** Host MIDI I/O +*/ +static bool Midi_Host_Open(void); +static void Midi_Host_Close(void); +static int Midi_Host_ReadByte(void); +static bool Midi_Host_WriteByte(Uint8 byte); + +#ifndef HAVE_PORTMIDI +static FILE *pMidiFhIn = NULL; /* File handle used for Midi input */ +static FILE *pMidiFhOut = NULL; /* File handle used for Midi output */ +#else +#include "portmidi.h" +#define INPUT_BUFFER_SIZE 1024 // PortMidi handles buffering +static PmStream* midiIn = NULL; // current midi input port +static PmStream* midiOut = NULL; // current midi output port +static int numInputs = 0; // number of available input ports +static int numOutputs = 0; // number of available output ports +static const PmDeviceInfo** inports = NULL; // array of available input ports +static const PmDeviceInfo** outports = NULL; // array of available output ports + +static bool Midi_Host_SwitchPort(const char* portName, bool forInput); +static int Midi_GetDataLength(Uint8 status); +static int Midi_SplitEvent(PmEvent* midiEvent, Uint8* msg); +static PmEvent* Midi_BuildEvent(Uint8 byte); +#endif + /** * Initialization: Open MIDI device. */ void Midi_Init(void) { - if (!ConfigureParams.Midi.bEnableMidi) - return; - - if (ConfigureParams.Midi.sMidiOutFileName[0]) + if (!Midi_Host_Open()) { - /* Open MIDI output file */ - pMidiFhOut = File_Open(ConfigureParams.Midi.sMidiOutFileName, "wb"); - if (!pMidiFhOut) - { - Log_AlertDlg(LOG_ERROR, "MIDI output file open failed. MIDI support disabled."); - ConfigureParams.Midi.bEnableMidi = false; - return; - } - setvbuf(pMidiFhOut, NULL, _IONBF, 0); /* No output buffering! */ - LOG_TRACE(TRACE_MIDI, "MIDI: Opened file '%s' for output\n", - ConfigureParams.Midi.sMidiOutFileName); - } - if (ConfigureParams.Midi.sMidiInFileName[0]) - { - /* Try to open MIDI input file */ - pMidiFhIn = File_Open(ConfigureParams.Midi.sMidiInFileName, "rb"); - if (!pMidiFhIn) - { - Log_AlertDlg(LOG_ERROR, "MIDI input file open failed. MIDI support disabled."); - ConfigureParams.Midi.bEnableMidi = false; - return; - } - setvbuf(pMidiFhIn, NULL, _IONBF, 0); /* No input buffering! */ - LOG_TRACE(TRACE_MIDI, "MIDI: Opened file '%s' for input\n", - ConfigureParams.Midi.sMidiInFileName); + Log_AlertDlg(LOG_ERROR, "MIDI i/o open failed. MIDI support disabled."); + ConfigureParams.Midi.bEnableMidi = false; } } @@ -108,9 +107,7 @@ void Midi_Init(void) */ void Midi_UnInit(void) { - pMidiFhIn = File_Close(pMidiFhIn); - pMidiFhOut = File_Close(pMidiFhOut); - + Midi_Host_Close(); CycInt_RemovePendingInterrupt(INTERRUPT_MIDI); } @@ -257,7 +254,8 @@ void Midi_Data_ReadByte(void) void Midi_Data_WriteByte(void) { Uint8 nTxDataByte; - + bool ok; + ACIA_AddWaitCycles (); /* Additional cycles when accessing the ACIA */ nTxDataByte = IoMem[0xfffc06]; @@ -287,20 +285,14 @@ void Midi_Data_WriteByte(void) if (!ConfigureParams.Midi.bEnableMidi) return; - if (pMidiFhOut) - { - int ret; - - /* Write the character to the output file: */ - ret = fputc(nTxDataByte, pMidiFhOut); + ok = Midi_Host_WriteByte(nTxDataByte); - /* If there was an error then stop the midi emulation */ - if (ret == EOF) - { - LOG_TRACE(TRACE_MIDI, "MIDI: write error -> stop MIDI\n"); - Midi_UnInit(); - return; - } + /* If there was an error then stop the midi emulation */ + if (!ok) + { + LOG_TRACE(TRACE_MIDI, "MIDI: write error -> stop MIDI\n"); + Midi_UnInit(); + return; } } @@ -331,25 +323,24 @@ void Midi_InterruptHandler_Update(void) } /* Read the bytes in, if we have any */ - if (pMidiFhIn && File_InputAvailable(pMidiFhIn)) + nInChar = Midi_Host_ReadByte(); + if (nInChar != EOF) { - nInChar = fgetc(pMidiFhIn); - if (nInChar != EOF) - { - LOG_TRACE(TRACE_MIDI, "MIDI: Read character -> $%x\n", nInChar); - /* Copy into our internal queue */ - nRxDataByte = nInChar; - MidiStatusRegister |= ACIA_SR_RX_FULL; + LOG_TRACE(TRACE_MIDI, "MIDI: Read character -> $%x\n", nInChar); + /* Copy into our internal queue */ + nRxDataByte = nInChar; + MidiStatusRegister |= ACIA_SR_RX_FULL; - /* Do we need to generate a receive interrupt? */ - MIDI_UpdateIRQ (); - } - else - { - LOG_TRACE(TRACE_MIDI, "MIDI: read error (doesn't stop MIDI)\n"); - clearerr(pMidiFhIn); - } + /* Do we need to generate a receive interrupt? */ + MIDI_UpdateIRQ (); + } +#ifndef HAVE_PORTMIDI + else if (pMidiFhIn) + { + LOG_TRACE(TRACE_MIDI, "MIDI: read error (doesn't stop MIDI)\n"); + clearerr(pMidiFhIn); } +#endif /* Set timer */ #ifdef OLD_CPU_SHIFT @@ -359,3 +350,452 @@ void Midi_InterruptHandler_Update(void) #endif } + +// ============================================================================ +// Host MIDI I/O +// ============================================================================ + +/** + * open MIDI streams + * return true for no errors + */ +static bool Midi_Host_Open(void) +{ +#ifndef HAVE_PORTMIDI + if (!ConfigureParams.Midi.bEnableMidi) + return true; + + if (ConfigureParams.Midi.sMidiOutFileName[0]) + { + /* Open MIDI output file */ + pMidiFhOut = File_Open(ConfigureParams.Midi.sMidiOutFileName, "wb"); + if (!pMidiFhOut) + return false; + setvbuf(pMidiFhOut, NULL, _IONBF, 0); /* No output buffering! */ + LOG_TRACE(TRACE_MIDI, "MIDI: Opened file '%s' for output\n", + ConfigureParams.Midi.sMidiOutFileName); + } + if (ConfigureParams.Midi.sMidiInFileName[0]) + { + /* Try to open MIDI input file */ + pMidiFhIn = File_Open(ConfigureParams.Midi.sMidiInFileName, "rb"); + if (!pMidiFhIn) + return false; + setvbuf(pMidiFhIn, NULL, _IONBF, 0); /* No input buffering! */ + LOG_TRACE(TRACE_MIDI, "MIDI: Opened file '%s' for input\n", + ConfigureParams.Midi.sMidiInFileName); + } + +#else + /* Need to always get MIDI device info, for MIDI setup dialog */ + int i; + int iindex = 0; + int oindex = 0; + int numPorts = 0; + + if (Pm_Initialize() != pmNoError) + { + LOG_TRACE(TRACE_MIDI, "MIDI: PortMidi initialization failed\n"); + return false; + } + // -- get rid of earlier portmidi descriptor arrays (if allocated) + // -- the information may be stale (USB Midi etc) + if (inports) + free (inports); + if (outports) + free (outports); + inports = outports = NULL; + numInputs = numOutputs = 0; + + // -- count number of input and output ports + numPorts = Pm_CountDevices(); + for (i = 0; i < numPorts; i++) + { + const PmDeviceInfo *info = Pm_GetDeviceInfo(i); + if (info->input) + numInputs++; + else if (info->output) + numOutputs++; + } + + // -- allocate descriptor arrays + inports = malloc(numInputs * sizeof(PmDeviceInfo*)); + outports = malloc(numOutputs * sizeof(PmDeviceInfo*)); + + // -- populate descriptor arrays + for (i = 0; i < numPorts; i++) + { + const PmDeviceInfo* info = Pm_GetDeviceInfo(i); + if (info) + { + LOG_TRACE(TRACE_MIDI, "MIDI: device %d: '%s'\n", i, info->name); + if (info->input) + inports[iindex++] = info; + if (info->output) + outports[oindex++] = info; + } + else + LOG_TRACE(TRACE_MIDI, "MIDI: info disappeared for device %d!\n", i); + } + + // -- open input and output ports according to configuration + if (ConfigureParams.Midi.sMidiInPortName[0]) + Midi_Host_SwitchPort(ConfigureParams.Midi.sMidiInPortName, true); + if (ConfigureParams.Midi.sMidiOutPortName[0]) + Midi_Host_SwitchPort(ConfigureParams.Midi.sMidiOutPortName, false); +#endif + + return true; +} + + +/* ---------------------------------------------------------------------------- */ +/** + * close MIDI streams + */ +static void Midi_Host_Close(void) +{ +#ifndef HAVE_PORTMIDI + pMidiFhIn = File_Close(pMidiFhIn); + pMidiFhOut = File_Close(pMidiFhOut); +#else + if (midiIn) + Pm_Close(midiIn); + if (midiOut) + Pm_Close(midiOut); + midiIn = midiOut = NULL; + + // Can't terminate PM or free descriptor arrays as this gets + // called by any write errors and GUI won't then work. + // Pm_Terminate(); +#endif +} + + + +/* ---------------------------------------------------------------------------- */ +/** + * returns port name for input or output port at 'index' + */ +const char* Midi_Host_GetPortName(int index, bool forInput) +{ +#ifdef HAVE_PORTMIDI + if (forInput && index < numInputs) + return inports[index]->name; + else if (!forInput && index < numOutputs) + return outports[index]->name; +#endif + + return NULL; +} + +/* ---------------------------------------------------------------------------- */ +/** + * returns port descriptor array index for input or output 'portName' + */ +int Midi_Host_GetPortIndex(const char* portName, bool forInput) +{ +#ifdef HAVE_PORTMIDI + int i = 0; + int numPorts = forInput ? numInputs : numOutputs; + const PmDeviceInfo** ports = forInput ? inports : outports; + + if (ports) + { + for (i = 0; i < numPorts; i++) + if (!strcmp(portName, ports[i]->name)) + return i; + } +#endif + + return -1; +} + +/** + * closes current midi port (if any) and opens 'portName' if MIDI enabled + * returns true if successful, false otherwise + */ +static bool Midi_Host_SwitchPort(const char* portName, bool forInput) +{ +#ifdef HAVE_PORTMIDI + int i, count; + bool err; + + if (!ConfigureParams.Midi.bEnableMidi) + return false; + + // -- find PortMidi index for 'portName' + count = Pm_CountDevices(); + for (i = 0; i < count; i++) + { + const PmDeviceInfo* info = Pm_GetDeviceInfo(i); + if (info) + { + if (forInput && !info->input) + continue; + else if (!forInput && info->input) + continue; + if (!strcmp(info->name, portName)) + break; + } + } + if (i >= count) + return false; + + // -- close current port in any case, then try open new one + if (forInput == true) + { + if (midiIn) { + Pm_Close(midiIn); + midiIn = NULL; + } + err = (Pm_OpenInput(&midiIn, i, NULL, INPUT_BUFFER_SIZE, NULL, NULL) == pmNoError); + LOG_TRACE(TRACE_MIDI, "MIDI: input port %d '%s' open %s\n", i, portName, err ? "succeeded" : "failed"); + return err; + } + else + { + if (midiOut) { + Pm_Close(midiOut); + midiOut = NULL; + } + err = (Pm_OpenOutput(&midiOut, i, NULL, 0, NULL, NULL, 0) == pmNoError); + LOG_TRACE(TRACE_MIDI, "MIDI: output port %d '%s' open %s\n", i, portName, err ? "succeeded" : "failed"); + return err; + } +#endif + return false; +} + + +/** + * returns byte from input stream, or EOF if it is empty + */ +static int Midi_Host_ReadByte(void) +{ +#ifndef HAVE_PORTMIDI + if (pMidiFhIn && File_InputAvailable(pMidiFhIn)) + return fgetc(pMidiFhIn); + else return EOF; +#else + static Uint8 msg[4]; + static Uint8 ibyte = 0; + static int bytesAvailable = 0; + + if (midiIn) + { + // -- we have not yet returned all bytes from previous event + if (bytesAvailable > 0) + { + bytesAvailable--; + return msg[ibyte++]; + } + + // -- read new event (if any) + else if (Pm_Poll(midiIn) == TRUE) { + PmEvent midiEvent; + if (Pm_Read(midiIn, &midiEvent, 1) != 1) + return EOF; + if ((bytesAvailable = Midi_SplitEvent(&midiEvent, msg)) > 0) + { + bytesAvailable--; + ibyte = 1; + return msg[0]; + } + } + } + + // -- no more midi data + return EOF; +#endif +} + + +/** + * writes 'byte' into output stream, returns true on success + */ +static bool Midi_Host_WriteByte(Uint8 byte) +{ +#ifndef HAVE_PORTMIDI + if (pMidiFhOut) + { + /* Write the character to the output file: */ + int ret = fputc(byte, pMidiFhOut); + return (ret != EOF); + } +#else + if (midiOut) + { + PmEvent* midiEvent = Midi_BuildEvent(byte); + if (midiEvent) + { + PmError error = Pm_Write(midiOut, midiEvent, 1); + if (error == pmNoError) + return true; + LOG_TRACE(TRACE_MIDI, "MIDI: PortMidi write error %d\n", error); + return false; + } + return true; + } +#endif + + return false; +} + + +#ifdef HAVE_PORTMIDI +// ============================================================================ +// PortMidi utils +// +// PortMidi (as most native MIDI APIs) operate on complete MIDI messages +// we need therefore handle running status, variable number of data bytes +// and sysex correctly. +// +// ============================================================================ + +/** + * return number of databytes that should accompany 'status' byte + * four bytes for sysex is a special case to simplify Midi_BuildEvent() + */ +static int Midi_GetDataLength(Uint8 status) +{ + static const Uint8 dataLength[] = { 2,2,2,2,1,2,2, 4,1,2,1,0,0,0,0 }; + + if (status >= 0xF8 || status == 0) + return 0; + if (status >= 0xF0) + return dataLength[(status & 0x0F) + 7]; + return dataLength[(status >> 4) - 8]; +} + +/** + * collect bytes until valid MIDI event has been formed / four bytes of sysex data has been gathered + * returns PmEvent when done, or NULL if it needs still more data + * see MIDI 1.0 Detailed Spec 4.2, pages A-1..A-2 for discussion on running status + */ +static PmEvent* Midi_BuildEvent(Uint8 byte) +{ + static const Uint8 shifts[] = { 0,8,16,24 }; + static PmEvent midiEvent = { 0,0 }; + static Uint32 midimsg; + static Uint8 runningStatus = 0; + static Uint8 bytesToWait = 0; + static Uint8 bytesCollected = 0; + static bool processingSysex = false; + + // -- status byte + if (byte & 0x80) + { + if (byte >= 0xF8) + { + midiEvent.message = Pm_Message(byte,0,0); + return &midiEvent; + } + else + { + processingSysex = false; + if (byte >= 0xF0) + { + runningStatus = 0; + if (byte == 0xF0) + { + processingSysex = true; + bytesCollected = 1; + } + else if (byte == 0xF7) + { + midiEvent.message = midimsg | (((Uint32)byte) << shifts[bytesCollected]); + midimsg = bytesToWait = bytesCollected = 0; + return &midiEvent; + } + else + bytesCollected = 0; + } + else + { + runningStatus = byte; + bytesCollected = 0; + } + } + midimsg = byte; + bytesToWait = Midi_GetDataLength(byte); + } + + // -- data byte + else + { + if (processingSysex) + midimsg |= ((Uint32)byte) << shifts[bytesCollected++]; + else + midimsg |= ((Uint32)byte) << shifts[++bytesCollected]; + if (bytesCollected >= bytesToWait) + { + midiEvent.message = midimsg; + midimsg = 0; + bytesCollected = 0; + bytesToWait = processingSysex ? 4 : 0; + return &midiEvent; + } + } + + return NULL; +} + + +/** + * extracts raw bytes from 'midiEvent' into 'msg' + * returns number of bytes available in 'msg' + * + * this method is required for sysex handling + * native framework has already handled running status + */ +static int Midi_SplitEvent(PmEvent* midiEvent, Uint8* msg) +{ + static bool processingSysex = false; + PmMessage midiMessage = midiEvent->message; + int i, bytesAvailable = 0; + + msg[0] = Pm_MessageStatus(midiMessage); + + // -- sysex start or continuation + if ((msg[0] == 0xF0) || (msg[0] < 0x80)) + { + if (msg[0] == 0xF0) + processingSysex = true; + + if (processingSysex) + { + for (i = 0; i <= 3; i++) + { + msg[i] = midiMessage & 0xFF; + bytesAvailable = i; + if (msg[i] == 0xF7) + { + processingSysex = false; + break; + } + midiMessage >>= 8; + } + } + else bytesAvailable = -1; + } + + // -- non-sysex + else + { + if (msg[0] < 0xF8) // non-realtime + { + processingSysex = false; + midiMessage >>= 8; + bytesAvailable = Midi_GetDataLength(msg[0]); + for (i = 1; i <= bytesAvailable; i++) + { + msg[i] = midiMessage & 0xFF; + midiMessage >>= 8; + } + } + } + + return bytesAvailable + 1; +} +#endif diff --git a/src/options.c b/src/options.c index 1be4f68..82a48bc 100644 --- a/src/options.c +++ b/src/options.c @@ -107,8 +107,12 @@ enum { OPT_JOYSTICK4, OPT_JOYSTICK5, OPT_PRINTER, +#ifdef HAVE_PORTMIDI + OPT_MIDI, +#else OPT_MIDI_IN, OPT_MIDI_OUT, +#endif OPT_RS232_IN, OPT_RS232_OUT, OPT_DRIVEA, /* disk options */ @@ -308,10 +312,15 @@ static const opt_t HatariOptions[] = { "<type>", "Set joystick type (none/keys/real) for given port" }, { OPT_PRINTER, NULL, "--printer", "<file>", "Enable printer support and write data to <file>" }, +#ifdef HAVE_PORTMIDI + { OPT_MIDI, NULL, "--midi", + "<bool>", "Whether to use MIDI (with PortMidi devices)" }, +#else { OPT_MIDI_IN, NULL, "--midi-in", "<file>", "Enable MIDI and use <file> as the input device" }, { OPT_MIDI_OUT, NULL, "--midi-out", "<file>", "Enable MIDI and use <file> as the output device" }, +#endif { OPT_RS232_IN, NULL, "--rs232-in", "<file>", "Enable serial port and use <file> as the input device" }, { OPT_RS232_OUT, NULL, "--rs232-out", @@ -1376,6 +1385,11 @@ bool Opt_ParseParameters(int argc, const char * const argv[]) &ConfigureParams.Printer.bEnablePrinting); break; +#ifdef HAVE_PORTMIDI + case OPT_MIDI: + ok = Opt_Bool(argv[++i], OPT_MIDI, &ConfigureParams.Midi.bEnableMidi); + break; +#else case OPT_MIDI_IN: i += 1; ok = Opt_StrCpy(OPT_MIDI_IN, true, ConfigureParams.Midi.sMidiInFileName, @@ -1389,7 +1403,8 @@ bool Opt_ParseParameters(int argc, const char * const argv[]) argv[i], sizeof(ConfigureParams.Midi.sMidiOutFileName), &ConfigureParams.Midi.bEnableMidi); break; - +#endif + case OPT_RS232_IN: i += 1; ok = Opt_StrCpy(OPT_RS232_IN, true, ConfigureParams.RS232.szInFileName, |
