/* hex receive from midi.library */
/*
    display incoming MIDI messages in Hex to the console.

    Shows proper method of waiting for, receiving, processing, and disposing
    of MIDI messages.
*/


#include <libraries/dos.h>
#include <clib/macros.h>
#include <midi/midi.h>
#include <functions.h>

#include <stdio.h>

void *MidiBase;

struct MDest *dest;
struct MRoute *route;
UBYTE *msg;		    /* buffer this in case we get shut down before freeing the current message */

main(argc,argv)
char **argv;
{
    char *sname = "MidiIn";
    static struct MRouteInfo routeinfo = { -1, -1 };	/* route spec's: receive all */

    printf ("MIDI Hex Display\n");

    if (argc > 1 && *argv[1] == '?') {
	printf ("usage: hr [source]\n");
	exit (1);
    }

    if (!(MidiBase = OpenLibrary (MIDINAME,MIDIVERSION))) {
	printf ("can't open midi.library\n");
	goto clean;
    }

    if (argc > 1) {	    /* if there's an argument, use it as an alt. source name */
	sname = argv[1];
    }
			    /* create out dest node (private) */
    if (!(dest = CreateMDest (NULL,NULL))) {
	printf ("can't create Dest\n");
	goto clean;
    }
			    /* create out route to MidiIn or whatever the user specified */
    if (!(route = MRouteDest (sname, dest, &routeinfo))) {
	printf ("can't create Route (can't find source \"%s\"?)\n",sname);
	goto clean;
    }

    process(dest);	    /* process until shutdown */

clean:
    cleanup();
}

_abort()		    /* abort routine called when CTRL-C is hit (Aztec) */
{
    fflush(stdout);
    cleanup();
    exit (1);
}

cleanup()
{
    if (msg) FreeMidiMsg (msg);
    if (route) DeleteMRoute (route);
    if (dest) DeleteMDest (dest);
    if (MidiBase) CloseLibrary (MidiBase);
}

process (dest)
struct MDest *dest;
{
    ULONG flags = SIGBREAKF_CTRL_C | (1L << dest->DestPort->mp_SigBit);

    while (!(Wait(flags) & SIGBREAKF_CTRL_C)) { 	/* wait until we get a message or CTRL-C is hit, quit on CTRL-C */
	while (msg = GetMidiMsg (dest)) {		/* get a message */
	    dumpmsg (msg);				/* print it */
	    FreeMidiMsg (msg);				/* free it */
	}
    }
}


dumpmsg (msg)
UBYTE *msg;
{
    long len = MidiMsgLength (msg);		/* find out how long the message is */

    if (*msg == MS_SYSEX) {			/* if it's a System Exclusive message... */
	dump (msg,MIN(len,8));			    /* only print the first 8 bytes */
	printf ("... (%ld bytes)\n",len);
    }
    else {					/* otherwise */
	dump (msg,MidiMsgLength(msg));		    /* print the whole message */
	printf ("\n");
    }
}


dump (s,len)					/* print len bytes in hex */
UBYTE *s;
long len;
{
    while (len--) printf ("%02x ",*s++);
}
