mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
Moved osd midi stuff to osd/modules/midi. Needed to touch a couple of
other files so that mame compiles and links. Tested SDL build (linux/windows).
This commit is contained in:
parent
1e81bd2557
commit
d7b9f653e3
@ -780,7 +780,7 @@ void cli_frontend::listmedia(const char *gamename)
|
||||
|
||||
void cli_frontend::listmididevices(const char *gamename)
|
||||
{
|
||||
osd_list_midi_devices();
|
||||
m_osd.list_midi_devices();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "emucore.h"
|
||||
#include "osdcore.h"
|
||||
#include "portmidi/portmidi.h"
|
||||
|
||||
bool g_print_verbose = false;
|
||||
|
||||
@ -166,425 +165,3 @@ void CLIB_DECL osd_printf_log(const char *format, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const int RX_EVENT_BUF_SIZE = 512;
|
||||
|
||||
#define MIDI_SYSEX 0xf0
|
||||
#define MIDI_EOX 0xf7
|
||||
|
||||
struct osd_midi_device
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
PortMidiStream *pmStream;
|
||||
PmEvent rx_evBuf[RX_EVENT_BUF_SIZE];
|
||||
#endif
|
||||
UINT8 xmit_in[4]; // Pm_Messages mean we can at most have 3 residue bytes
|
||||
int xmit_cnt;
|
||||
UINT8 last_status;
|
||||
bool rx_sysex;
|
||||
};
|
||||
|
||||
void osd_list_midi_devices(void)
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
int num_devs = Pm_CountDevices();
|
||||
const PmDeviceInfo *pmInfo;
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (num_devs == 0)
|
||||
{
|
||||
printf("No MIDI ports were found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("MIDI input ports:\n");
|
||||
for (int i = 0; i < num_devs; i++)
|
||||
{
|
||||
pmInfo = Pm_GetDeviceInfo(i);
|
||||
|
||||
if (pmInfo->input)
|
||||
{
|
||||
printf("%s %s\n", pmInfo->name, (i == Pm_GetDefaultInputDeviceID()) ? "(default)" : "");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nMIDI output ports:\n");
|
||||
for (int i = 0; i < num_devs; i++)
|
||||
{
|
||||
pmInfo = Pm_GetDeviceInfo(i);
|
||||
|
||||
if (pmInfo->output)
|
||||
{
|
||||
printf("%s %s\n", pmInfo->name, (i == Pm_GetDefaultOutputDeviceID()) ? "(default)" : "");
|
||||
}
|
||||
}
|
||||
#else
|
||||
printf("\nMIDI is not supported in this build\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
osd_midi_device *osd_open_midi_input(const char *devname)
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
int num_devs = Pm_CountDevices();
|
||||
int found_dev = -1;
|
||||
const PmDeviceInfo *pmInfo;
|
||||
PortMidiStream *stm;
|
||||
osd_midi_device *ret;
|
||||
|
||||
if (!strcmp("default", devname))
|
||||
{
|
||||
found_dev = Pm_GetDefaultInputDeviceID();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < num_devs; i++)
|
||||
{
|
||||
pmInfo = Pm_GetDeviceInfo(i);
|
||||
|
||||
if (pmInfo->input)
|
||||
{
|
||||
if (!strcmp(devname, pmInfo->name))
|
||||
{
|
||||
found_dev = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_dev >= 0)
|
||||
{
|
||||
if (Pm_OpenInput(&stm, found_dev, NULL, RX_EVENT_BUF_SIZE, NULL, NULL) == pmNoError)
|
||||
{
|
||||
ret = (osd_midi_device *)osd_malloc(sizeof(osd_midi_device));
|
||||
memset(ret, 0, sizeof(osd_midi_device));
|
||||
ret->pmStream = stm;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Couldn't open PM device\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
osd_midi_device *osd_open_midi_output(const char *devname)
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
int num_devs = Pm_CountDevices();
|
||||
int found_dev = -1;
|
||||
const PmDeviceInfo *pmInfo;
|
||||
PortMidiStream *stm;
|
||||
osd_midi_device *ret;
|
||||
|
||||
if (!strcmp("default", devname))
|
||||
{
|
||||
found_dev = Pm_GetDefaultOutputDeviceID();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < num_devs; i++)
|
||||
{
|
||||
pmInfo = Pm_GetDeviceInfo(i);
|
||||
|
||||
if (pmInfo->output)
|
||||
{
|
||||
if (!strcmp(devname, pmInfo->name))
|
||||
{
|
||||
found_dev = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_dev >= 0)
|
||||
{
|
||||
if (Pm_OpenOutput(&stm, found_dev, NULL, 100, NULL, NULL, 0) == pmNoError)
|
||||
{
|
||||
ret = (osd_midi_device *)osd_malloc(sizeof(osd_midi_device));
|
||||
memset(ret, 0, sizeof(osd_midi_device));
|
||||
ret->pmStream = stm;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Couldn't open PM device\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void osd_close_midi_channel(osd_midi_device *dev)
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
Pm_Close(dev->pmStream);
|
||||
osd_free(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool osd_poll_midi_channel(osd_midi_device *dev)
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
PmError chk = Pm_Poll(dev->pmStream);
|
||||
|
||||
return (chk == pmGotData) ? true : false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int osd_read_midi_channel(osd_midi_device *dev, UINT8 *pOut)
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
int msgsRead = Pm_Read(dev->pmStream, dev->rx_evBuf, RX_EVENT_BUF_SIZE);
|
||||
int bytesOut = 0;
|
||||
|
||||
if (msgsRead <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int msg = 0; msg < msgsRead; msg++)
|
||||
{
|
||||
UINT8 status = Pm_MessageStatus(dev->rx_evBuf[msg].message);
|
||||
|
||||
if (dev->rx_sysex)
|
||||
{
|
||||
if (status & 0x80) // sys real-time imposing on us?
|
||||
{
|
||||
if ((status == 0xf2) || (status == 0xf3))
|
||||
{
|
||||
*pOut++ = status;
|
||||
*pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
|
||||
*pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
|
||||
bytesOut += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pOut++ = status;
|
||||
bytesOut++;
|
||||
if (status == MIDI_EOX)
|
||||
{
|
||||
dev->rx_sysex = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // shift out the sysex bytes
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
UINT8 byte = dev->rx_evBuf[msg].message & 0xff;
|
||||
*pOut++ = byte;
|
||||
bytesOut++;
|
||||
if (byte == MIDI_EOX)
|
||||
{
|
||||
dev->rx_sysex = false;
|
||||
break;
|
||||
}
|
||||
dev->rx_evBuf[msg].message >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ((status>>4) & 0xf)
|
||||
{
|
||||
case 0xc: // 2-byte messages
|
||||
case 0xd:
|
||||
*pOut++ = status;
|
||||
*pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
|
||||
bytesOut += 2;
|
||||
break;
|
||||
|
||||
case 0xf: // system common
|
||||
switch (status & 0xf)
|
||||
{
|
||||
case 0: // System Exclusive
|
||||
{
|
||||
*pOut++ = status; // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe
|
||||
*pOut++ = (dev->rx_evBuf[msg].message>>8) & 0xff;
|
||||
*pOut++ = (dev->rx_evBuf[msg].message>>16) & 0xff;
|
||||
UINT8 last = *pOut++ = (dev->rx_evBuf[msg].message>>24) & 0xff;
|
||||
bytesOut += 4;
|
||||
dev->rx_sysex = (last != MIDI_EOX);
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: // End of System Exclusive
|
||||
*pOut++ = status;
|
||||
bytesOut += 1;
|
||||
dev->rx_sysex = false;
|
||||
break;
|
||||
|
||||
case 2: // song pos
|
||||
case 3: // song select
|
||||
*pOut++ = status;
|
||||
*pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
|
||||
*pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
|
||||
bytesOut += 3;
|
||||
break;
|
||||
|
||||
default: // all other defined Fx messages are 1 byte
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*pOut++ = status;
|
||||
*pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message);
|
||||
*pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message);
|
||||
bytesOut += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bytesOut;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void osd_write_midi_channel(osd_midi_device *dev, UINT8 data)
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
int bytes_needed = 0;
|
||||
PmEvent ev;
|
||||
ev.timestamp = 0; // use the current time
|
||||
|
||||
// printf("write: %02x (%d)\n", data, dev->xmit_cnt);
|
||||
|
||||
// reject data bytes when no valid status exists
|
||||
if ((dev->last_status == 0) && !(data & 0x80))
|
||||
{
|
||||
dev->xmit_cnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->xmit_cnt >= 4)
|
||||
{
|
||||
printf("MIDI out: packet assembly overflow, contact MAMEdev!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// handle sysex
|
||||
if (dev->last_status == MIDI_SYSEX)
|
||||
{
|
||||
// printf("sysex: %02x (%d)\n", data, dev->xmit_cnt);
|
||||
|
||||
// if we get a status that isn't sysex, assume it's system common
|
||||
if ((data & 0x80) && (data != MIDI_EOX))
|
||||
{
|
||||
// printf("common during sysex!\n");
|
||||
ev.message = Pm_Message(data, 0, 0);
|
||||
Pm_Write(dev->pmStream, &ev, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
dev->xmit_in[dev->xmit_cnt++] = data;
|
||||
|
||||
// if EOX or 4 bytes filled, transmit 4 bytes
|
||||
if ((dev->xmit_cnt == 4) || (data == MIDI_EOX))
|
||||
{
|
||||
ev.message = dev->xmit_in[0] | (dev->xmit_in[1]<<8) | (dev->xmit_in[2]<<16) | (dev->xmit_in[3]<<24);
|
||||
Pm_Write(dev->pmStream, &ev, 1);
|
||||
dev->xmit_in[0] = dev->xmit_in[1] = dev->xmit_in[2] = dev->xmit_in[3] = 0;
|
||||
dev->xmit_cnt = 0;
|
||||
|
||||
// printf("SysEx packet: %08x\n", ev.message);
|
||||
|
||||
// if this is EOX, kill the running status
|
||||
if (data == MIDI_EOX)
|
||||
{
|
||||
dev->last_status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// handle running status. don't allow system real-time messages to be considered as running status.
|
||||
if ((dev->xmit_cnt == 0) && (data & 0x80) && (data < 0xf8))
|
||||
{
|
||||
dev->last_status = data;
|
||||
}
|
||||
|
||||
if ((dev->xmit_cnt == 0) && !(data & 0x80))
|
||||
{
|
||||
dev->xmit_in[dev->xmit_cnt++] = dev->last_status;
|
||||
dev->xmit_in[dev->xmit_cnt++] = data;
|
||||
// printf("\trunning status: [%d] = %02x, [%d] = %02x, last_status = %02x\n", dev->xmit_cnt-2, dev->last_status, dev->xmit_cnt-1, data, dev->last_status);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->xmit_in[dev->xmit_cnt++] = data;
|
||||
// printf("\tNRS: [%d] = %02x\n", dev->xmit_cnt-1, data);
|
||||
}
|
||||
|
||||
if ((dev->xmit_cnt == 1) && (dev->xmit_in[0] == MIDI_SYSEX))
|
||||
{
|
||||
// printf("Start SysEx!\n");
|
||||
dev->last_status = MIDI_SYSEX;
|
||||
return;
|
||||
}
|
||||
|
||||
// are we there yet?
|
||||
// printf("status check: %02x\n", dev->xmit_in[0]);
|
||||
switch ((dev->xmit_in[0]>>4) & 0xf)
|
||||
{
|
||||
case 0xc: // 2-byte messages
|
||||
case 0xd:
|
||||
bytes_needed = 2;
|
||||
break;
|
||||
|
||||
case 0xf: // system common
|
||||
switch (dev->xmit_in[0] & 0xf)
|
||||
{
|
||||
case 0: // System Exclusive is handled above
|
||||
break;
|
||||
|
||||
case 7: // End of System Exclusive
|
||||
bytes_needed = 1;
|
||||
break;
|
||||
|
||||
case 2: // song pos
|
||||
case 3: // song select
|
||||
bytes_needed = 3;
|
||||
break;
|
||||
|
||||
default: // all other defined Fx messages are 1 byte
|
||||
bytes_needed = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
bytes_needed = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->xmit_cnt == bytes_needed)
|
||||
{
|
||||
ev.message = Pm_Message(dev->xmit_in[0], dev->xmit_in[1], dev->xmit_in[2]);
|
||||
Pm_Write(dev->pmStream, &ev, 1);
|
||||
dev->xmit_cnt = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -874,6 +874,8 @@ file_error osd_get_full_path(char **dst, const char *path);
|
||||
***************************************************************************/
|
||||
struct osd_midi_device;
|
||||
|
||||
bool osd_midi_init();
|
||||
void osd_midi_exit();
|
||||
void osd_list_midi_devices(void);
|
||||
// free result with osd_close_midi_channel()
|
||||
osd_midi_device *osd_open_midi_input(const char *devname);
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "osdepend.h"
|
||||
#include "portmidi/portmidi.h"
|
||||
#include "modules/sound/none.h"
|
||||
#include "modules/debugger/none.h"
|
||||
#include "modules/debugger/debugint.h"
|
||||
@ -474,15 +473,6 @@ bool osd_interface::network_init()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool osd_interface::midi_init()
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
Pm_Initialize();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void osd_interface::exit_subsystems()
|
||||
{
|
||||
video_exit();
|
||||
@ -521,13 +511,6 @@ void osd_interface::network_exit()
|
||||
{
|
||||
}
|
||||
|
||||
void osd_interface::midi_exit()
|
||||
{
|
||||
#ifndef DISABLE_MIDI
|
||||
Pm_Terminate();
|
||||
#endif
|
||||
}
|
||||
|
||||
void osd_interface::osd_exit()
|
||||
{
|
||||
exit_subsystems();
|
||||
|
@ -167,6 +167,13 @@ public:
|
||||
// video overridables
|
||||
virtual void *get_slider_list();
|
||||
|
||||
// midi overridables
|
||||
// FIXME: this should return a list of devices, not list them on stdout
|
||||
virtual void list_midi_devices(void);
|
||||
|
||||
// FIXME: everything below seems to be osd specific and not part of
|
||||
// this INTERFACE but part of the osd IMPLEMENTATION
|
||||
|
||||
void init_subsystems();
|
||||
|
||||
virtual bool video_init();
|
||||
|
@ -394,7 +394,10 @@ endif
|
||||
SDLSRC = $(SRC)/osd/$(OSD)
|
||||
SDLOBJ = $(OBJ)/osd/$(OSD)
|
||||
|
||||
OBJDIRS += $(SDLOBJ) $(OSDOBJ)/modules/sync $(OSDOBJ)/modules/lib
|
||||
OBJDIRS += $(SDLOBJ) \
|
||||
$(OSDOBJ)/modules/sync \
|
||||
$(OSDOBJ)/modules/lib \
|
||||
$(OSDOBJ)/modules/midi \
|
||||
|
||||
#-------------------------------------------------
|
||||
# OSD core library
|
||||
@ -430,12 +433,14 @@ OSDOBJS = \
|
||||
$(SDLOBJ)/output.o \
|
||||
$(SDLOBJ)/watchdog.o \
|
||||
|
||||
ifeq ($(BASE_TARGETOS),win32)
|
||||
OSDOBJS += $(OSDOBJ)/modules/sound/direct_sound.o
|
||||
ifdef NO_USE_MIDI
|
||||
OSDOBJS += $(OSDOBJ)/modules/midi/none.o
|
||||
else
|
||||
OSDOBJS += $(OSDOBJ)/modules/midi/portmidi.o
|
||||
endif
|
||||
|
||||
ifdef NO_USE_MIDI
|
||||
DEFS += -DDISABLE_MIDI=1
|
||||
ifeq ($(BASE_TARGETOS),win32)
|
||||
OSDOBJS += $(OSDOBJ)/modules/sound/direct_sound.o
|
||||
endif
|
||||
|
||||
# Add SDL2.0 support
|
||||
|
@ -1438,3 +1438,28 @@ bool sdl_osd_interface::font_get_bitmap(osd_font font, unicode_char chnum, bitma
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------
|
||||
// FIXME: Doesn't belong here but there's no better
|
||||
// place currently.
|
||||
//-------------------------------------------------
|
||||
|
||||
bool osd_interface::midi_init()
|
||||
{
|
||||
// this should be done on the OS_level
|
||||
return osd_midi_init();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// list_midi_devices - list available midi devices
|
||||
//-------------------------------------------------
|
||||
|
||||
void osd_interface::list_midi_devices(void)
|
||||
{
|
||||
osd_list_midi_devices();
|
||||
}
|
||||
|
||||
void osd_interface::midi_exit()
|
||||
{
|
||||
osd_midi_exit();
|
||||
}
|
||||
|
@ -87,7 +87,10 @@ WINOBJ = $(OBJ)/osd/$(OSD)
|
||||
OSDSRC = $(SRC)/osd
|
||||
OSDOBJ = $(OBJ)/osd
|
||||
|
||||
OBJDIRS += $(WINOBJ) $(OSDOBJ)/modules/sync $(OSDOBJ)/modules/lib
|
||||
OBJDIRS += $(WINOBJ) \
|
||||
$(OSDOBJ)/modules/sync \
|
||||
$(OSDOBJ)/modules/lib \
|
||||
$(OSDOBJ)/modules/midi \
|
||||
|
||||
ifdef USE_QTDEBUG
|
||||
OBJDIRS += $(OSDOBJ)/modules/debugger/qt
|
||||
@ -374,7 +377,8 @@ OSDOBJS = \
|
||||
$(WINOBJ)/video.o \
|
||||
$(WINOBJ)/window.o \
|
||||
$(WINOBJ)/winmenu.o \
|
||||
$(WINOBJ)/winmain.o
|
||||
$(WINOBJ)/winmain.o \
|
||||
$(OSDOBJ)/modules/midi/portmidi.o \
|
||||
|
||||
ifdef USE_SDL
|
||||
OSDOBJS += \
|
||||
|
Loading…
Reference in New Issue
Block a user