/* 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 MidiPackets.
*/


#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;
struct MidiPacket *packet;  /* buffer this in case we get shut down before freeing the current message */

main(argc,argv)
char **argv;
{
    char *sname = "MidiIn";

    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, NULL))) {        /* use default route on our MDest (defaults to everything) */
	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 (packet) FreeMidiPacket (packet);
    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 (packet = GetMidiPacket (dest)) {         /* get a packet */
	    dumppacket (packet);                        /* print it */
	    FreeMidiPacket (packet);                    /* free it */
	}
    }
}


dumppacket (packet)
struct MidiPacket *packet;
{
    if (packet->Type == MMF_SYSEX) {                /* if it's a System Exclusive message... */
	dump (packet->MidiMsg,MIN(packet->Length,8));   /* only print the first 8 bytes */
	printf ("... (%d bytes)\n",packet->Length);
    }
    else {					    /* otherwise */
	dump (packet->MidiMsg,packet->Length);          /* print the whole message */
	printf ("\n");
    }
}


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