home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume6 / glib / part07 / amigmach.c next >
Encoding:
C/C++ Source or Header  |  1989-05-14  |  12.8 KB  |  714 lines

  1. /* $Id: amigmach.c,v 1.6 89/05/06 17:13:10 lee Exp $
  2.  *
  3.  * GLIB - a Generic LIBrarian and editor for synths
  4.  *
  5.  * Machine dependent stuff.
  6.  *
  7.  * Amiga version.
  8.  * Alan Bland
  9.  *
  10.  * modifications by Mark Rinfret and Dave Weiler
  11.  * $Log:    amigmach.c,v $
  12.  * Revision 1.6  89/05/06  17:13:10  lee
  13.  * rel. to comp.sources.misc
  14.  * 
  15.  */
  16.  
  17. #include "glib.h"
  18. #include <stdio.h>
  19. #include <ctype.h>
  20.  
  21. #ifndef AZTEC_C
  22. #include <dos.h>
  23. #endif
  24. #include <intuition/intuition.h>
  25. #include <exec/types.h>
  26. #include <exec/ports.h>
  27. #include <exec/io.h>
  28. #include <exec/devices.h>
  29. #include <exec/memory.h>
  30. #include <devices/serial.h>
  31.  
  32. #ifdef ARP
  33.     #include <libraries/arpbase.h>
  34.     #include <arpfunctions.h>
  35. #endif
  36.  
  37. #ifdef AZTEC_C
  38. #include <libraries/dos.h>
  39. #include <libraries/dosextens.h>
  40. #include <functions.h>
  41. #else
  42. #include <proto/exec.h>
  43. #include <proto/intuition.h>
  44. #endif
  45.  
  46. #ifdef ARP
  47.     char FileName[FCHARS+1];
  48.     char DirName[DSIZE+1];
  49.     struct FileRequester MyFileRequest =
  50.         {
  51.         "GLIB file name -->",
  52.         FileName,
  53.         DirName,
  54.         0,
  55.         0,0,
  56.         0,
  57.         0
  58.         };
  59.     int FileRequestImminent;
  60. #else
  61.     struct IntuitionBase *IntuitionBase;
  62.     struct GfxBase *GfxBase;
  63. #endif
  64.  
  65. struct Screen *S;
  66. struct Window *W;
  67. struct RastPort *R;
  68.  
  69. int Rows, Cols;
  70.  
  71. #define TOPEDGE 8    /* how much of screen bar to show */
  72. int WindowWidth = 640;
  73. int WindowHeight = 200 - TOPEDGE;
  74.  
  75. /* standard WB colors */
  76. #define BLUE 0
  77. #define WHITE 1
  78. #define BLACK 2
  79. #define ORANGE 3
  80.  
  81.  
  82. hello()
  83. {
  84.     windinit();
  85.     openmidi();
  86. }
  87.  
  88. bye()
  89. {
  90.     closemidi();
  91.     windexit(0);
  92. }
  93.  
  94. int MouseX, MouseY, MouseButtons;
  95. int Mouseok = 0;
  96.  
  97. /* getmouse - get current row and column of mouse */
  98. getmouse(amr,amc)
  99. int *amr;
  100. int *amc;
  101. {
  102.     *amr = MouseY / 8;
  103.     *amc = MouseX / 8;
  104. }
  105.  
  106. /* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */
  107. statmouse()
  108. {
  109.     nextevent(MOUSEBUTTONS, 0);
  110.     return MouseButtons;
  111. }
  112.  
  113. /* Return when either a console key or mouse button is pressed. */
  114. mouseorkey()
  115. {
  116.     return nextevent(MOUSEBUTTONS | VANILLAKEY, 1);
  117. }
  118.  
  119. flushconsole()
  120. {
  121.     while (nextevent(VANILLAKEY, 0) >= 0) ;
  122. }
  123.  
  124. getconsole()
  125. {
  126.     return nextevent(VANILLAKEY, 1);
  127. }
  128.  
  129. cursor(state)
  130. int state;
  131. {
  132.     int x, y;
  133.     x = R->cp_x;
  134.     y = R->cp_y - R->Font->tf_Baseline;
  135.     SetDrMd(R, COMPLEMENT);
  136.     RectFill(R, x, y, x+8, y+R->Font->tf_YSize-1);
  137.     SetDrMd(R, JAM2);
  138. }
  139.  
  140. nextevent(flags, wait)
  141. long flags;
  142. int wait;
  143. {
  144.     register int class, code;
  145.     register struct IntuiMessage *message;
  146.     int result;
  147.  
  148.     cursor(1);
  149.     ModifyIDCMP(W, CLOSEWINDOW | flags);
  150.     while (1)
  151.     {
  152.         if (wait)
  153.         {
  154.             /* get next event, waiting if none are available */
  155.             while ((message = (struct IntuiMessage *)GetMsg(W->UserPort)) == NULL)
  156.             {
  157.             Wait(1<<W->UserPort->mp_SigBit);
  158.             }
  159.         }
  160.         else
  161.         {
  162.             /* get next event, but return if none are available */
  163.             message = (struct IntuiMessage *)GetMsg(W->UserPort);
  164.             if (message == NULL)
  165.             {
  166.             result = -1;
  167.             break;
  168.             }
  169.         }
  170.         class = message->Class;
  171.         code = message->Code;
  172.         MouseX = message->MouseX;
  173.         MouseY = message->MouseY;
  174.         ReplyMsg((struct Message *)message);
  175.  
  176.         switch (class)
  177.         {
  178.         case VANILLAKEY:
  179.             result = code;
  180.             break;
  181.         case CLOSEWINDOW:
  182.             result = 'q';
  183.             break;
  184.         case MOUSEBUTTONS:
  185.             switch (code)
  186.             {
  187.             case SELECTDOWN:
  188.                 MouseButtons = 1;
  189.                 break;
  190.             case MENUDOWN:
  191.                 MouseButtons = 2;
  192.                 break;
  193.             default:
  194.                 MouseButtons = 0;
  195.                 break;
  196.             }
  197.             result = MOUSE;
  198.             break;
  199.         default:
  200.             continue;
  201.         }
  202.         break;
  203.     }
  204.     cursor(0);
  205.     return result;
  206. }
  207.  
  208. /*------------------------------------------------------------------------
  209.  * MIDI I/O Routines for Amiga.
  210.  *
  211.  * Uses low-level serial I/O for simultaneous reads and writes.
  212.  */
  213.  
  214. struct MsgPort    *MidiInPort, *MidiOutPort;
  215. struct IOExtSer    *MidiIn, *MidiOut;
  216. int    SerOpen = 0;
  217.  
  218. unsigned char   MidiInBuf;
  219. int    MidiDataAvail = 0;
  220.  
  221. /*
  222.  * start an asynchronous read request from MIDI IN
  223.  */
  224.  
  225. startmidiread()
  226. {
  227.     MidiIn->IOSer.io_Data = (APTR) &MidiInBuf;
  228.     MidiIn->IOSer.io_Length = 1;
  229.     MidiIn->IOSer.io_Command = CMD_READ;
  230.     MidiIn->IOSer.io_Flags = IOF_QUICK;    /* use quick I/O */
  231.     BeginIO((struct IORequest *) MidiIn);
  232.     /* did I/O complete quickly? */
  233.     if ((MidiIn->IOSer.io_Flags & IOF_QUICK)) {
  234.         /* wow, data's coming in fast! */
  235.         MidiDataAvail = 1;
  236.     } else {
  237.         /* no data this time, it'll arrive later */
  238.         MidiDataAvail = 0;
  239.     }
  240. }
  241.  
  242. /*
  243.  * get a byte from MIDI IN.
  244.  * assumes startmidiread has been previously done.  if statmidi has been
  245.  * checked, this function will not wait.  otherwise, it will wait for
  246.  * a single byte to arrive if none is available.
  247.  */
  248. unsigned
  249. getmidi()
  250. {
  251.     register struct Message    *io;
  252.         unsigned result;
  253.  
  254.     /* return previously-received data, if available */
  255.     if (MidiDataAvail) {
  256.                 result = MidiInBuf & 0xff;
  257.         /* start a new I/O */
  258.         startmidiread();
  259.         return result;
  260.     }
  261.  
  262.     /* read next available byte */
  263.     io = (struct Message *) CheckIO((struct IORequest *) MidiIn);
  264.     if (io == FALSE) {
  265.         /* wait for next byte */
  266.         WaitIO((struct IORequest *) MidiIn);
  267.         io = &MidiIn->IOSer.io_Message;
  268.     }
  269.  
  270.     Remove(&io->mn_Node);
  271.     result = MidiInBuf;
  272.     startmidiread();    /* start I/O for next byte */
  273.     return result;
  274. }
  275.  
  276. /*
  277.  * write one byte to MIDI OUT
  278.  */
  279.  
  280. sendmidi(c)
  281. int c;
  282. {
  283.     char    buf = c;
  284. #ifdef STATISTICS
  285.         long    bytesOut;
  286.         long    start, totalTime, average;
  287.  
  288.  
  289.         ++bytesOut;
  290.         start = milliclock();
  291. #endif
  292.     MidiOut->IOSer.io_Data = (APTR) &buf;
  293.     MidiOut->IOSer.io_Length = 1;
  294.     MidiOut->IOSer.io_Command = CMD_WRITE;
  295.     DoIO((struct IORequest *) MidiOut);    /* synchronous request */
  296. #ifdef STATISTICS
  297.         totalTime += milliclock() - start;
  298.         average = totalTime / bytesOut;
  299. #endif
  300. }
  301.  
  302. /*  FUNCTION
  303.         sendmulti - send multiple bytes to midi device
  304.  
  305.     SYNOPSIS
  306.         void sendmulti(buffer, count)
  307.                 char    *buffer;
  308.                 int     count;
  309.  
  310.     DESCRIPTION
  311.         sendmulti transfers <count> bytes from <buffer> to the currently
  312.         open midi device.
  313.  
  314. */
  315.  
  316. void
  317. sendmulti(buffer, count)
  318.     char *buffer; int count;
  319. {
  320. #ifdef STATISTICS
  321.         long    bytesOut;
  322.         long    start, totalTime, average;
  323.  
  324.  
  325.         bytesOut += count;
  326.         start = milliclock();
  327. #endif
  328.         MidiOut->IOSer.io_Data = (APTR) buffer;
  329.         MidiOut->IOSer.io_Length = count;
  330.         MidiOut->IOSer.io_Command = CMD_WRITE;
  331.         DoIO((struct IORequest *) MidiOut);     /* synchronous request */
  332. #ifdef STATISTICS
  333.         totalTime += milliclock() - start;
  334.         average = totalTime / bytesOut;
  335. #endif
  336.  
  337.  
  338. }
  339.  
  340. /*
  341.  * check if any midi data is waiting to be received
  342.  */
  343. statmidi()
  344. {
  345.     /* check if data has previously been received */
  346.     if (MidiDataAvail) return 1;
  347.  
  348.     /* check if i/o has completed */
  349.     return (CheckIO((struct IORequest *) MidiIn) == FALSE) ? 0 : 1;
  350. }
  351.  
  352. openmidi()
  353. {
  354.     /* create message port for serial device */
  355.         MidiInPort = (struct MsgPort *) CreatePort(SERIALNAME,0L);
  356.     if (MidiInPort == NULL) fatal("Can't create MidiInPort");
  357.  
  358.     /* create i/o request block for serial device */
  359.     MidiIn = (struct IOExtSer *)
  360.                 CreateExtIO(MidiInPort, (long) sizeof(struct IOExtSer));
  361.     if (MidiIn == NULL) fatal("Can't create MidiIn");
  362.  
  363.     /* open the serial device */
  364.     MidiIn->io_SerFlags = SERF_SHARED;
  365.     SerOpen = OpenDevice(SERIALNAME,0,(struct IORequest *) MidiIn,0) == 0 ? 1 : 0;
  366.     if (SerOpen == 0) fatal("Can't open serial.device");
  367.  
  368.     /* set serial device parameters */
  369.     MidiIn->io_Baud = 31250;
  370.         MidiIn->io_RBufLen = 512;       /* large input buffer - if your synth
  371.                      * sends dumps larger than this you
  372.                      * will have to increase it. */
  373.     MidiIn->io_SerFlags = SERF_RAD_BOOGIE;
  374.     MidiIn->IOSer.io_Command = SDCMD_SETPARAMS;
  375.     DoIO((struct IORequest *) MidiIn);
  376.  
  377.     /* clone MidiIn into MidiOut to allow simultaneous i/o */
  378.         MidiOutPort = (struct MsgPort *) CreatePort("MidiOut",0L);
  379.     if (MidiOutPort == NULL) fatal("Can't create MidiOutPort");
  380.  
  381.     MidiOut = (struct IOExtSer *)
  382.             CreateExtIO(MidiOutPort, sizeof(struct IOExtSer));
  383.     *MidiOut = *MidiIn;
  384.     MidiOut->IOSer.io_Message.mn_ReplyPort = MidiOutPort;
  385.  
  386.     /* get the MIDI IN port started */
  387.     startmidiread();
  388. }
  389.  
  390. closemidi()
  391. {
  392.     if (SerOpen) CloseDevice((struct IORequest *)MidiIn);
  393.     if (MidiIn) DeleteExtIO((struct IORequest *)MidiIn);
  394.     if (MidiOut) DeleteExtIO((struct IORequest *)MidiOut);
  395.     if (MidiInPort) DeletePort(MidiInPort);
  396.     if (MidiOutPort) DeletePort(MidiOutPort);
  397. }
  398.  
  399. flushmidi()
  400. {
  401.     while ( STATMIDI )
  402.         getmidi();
  403. }
  404.  
  405. #ifdef AZTEC_C
  406. long milliclock()
  407. {
  408.     static long secs, startSecs, micros, startMicros;
  409.     long product;
  410.  
  411.     CurrentTime(&secs, µs);
  412.     if (startSecs == 0) {
  413.         startSecs = secs;
  414.         startMicros = micros;
  415.     }
  416.     product =  ((secs - startSecs) * 1000L +
  417.                 (micros - startMicros)/1000L);
  418.     return product;
  419. }
  420. #else
  421. long milliclock()
  422. {
  423.     unsigned int clock[2];
  424.     long milli;
  425.     timer(clock);
  426.     milli = clock[0] * 1000 + clock[1] / 1000;
  427.     return milli;
  428. }
  429. #endif
  430.  
  431. millisleep(n)
  432. {
  433.     long ticks = n/20;
  434.  
  435.     if (ticks) Delay(ticks);        /* Avoid the Delay(0) bug! */
  436. }
  437.  
  438. char *
  439. alloc(n)
  440. {
  441.     char *p;
  442.  
  443.     if ( (p=malloc((unsigned)n)) == (char *)NULL ) {
  444.         fatal("GLIB is out of memory!");
  445.     }
  446.     return(p);
  447. }
  448.  
  449. struct TextAttr font =
  450. {
  451.     "topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT
  452. };
  453.  
  454. struct NewScreen ns =
  455. {
  456.     0,0,640,200,2,BLACK,WHITE,HIRES,CUSTOMSCREEN,&font,"",NULL,NULL
  457. };
  458.  
  459. windinit()
  460. {
  461.     struct NewWindow nw;
  462.  
  463.     if (S != NULL) return;
  464.  
  465. #ifdef ARP
  466.     FileRequestImminent = FALSE;
  467.     /* libraries opened by arpc.o */
  468. #else
  469.     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
  470.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
  471.     if (IntuitionBase == NULL || GfxBase == NULL) exit(1);
  472. #endif
  473.  
  474.     if ((S = (struct Screen *) OpenScreen(&ns)) == NULL) exit(1);
  475.  
  476.     nw.LeftEdge = 0;
  477.     nw.TopEdge = TOPEDGE;
  478.     nw.Width = WindowWidth;
  479.     nw.Height = WindowHeight;
  480.     nw.DetailPen = BLACK;
  481.     nw.BlockPen = WHITE;
  482.     nw.Title = NULL;
  483.     nw.Flags = SMART_REFRESH | ACTIVATE | BACKDROP |
  484.            BORDERLESS | NOCAREREFRESH | RMBTRAP;
  485.     nw.IDCMPFlags = CLOSEWINDOW | VANILLAKEY;
  486.     nw.Type = CUSTOMSCREEN;
  487.     nw.FirstGadget = NULL;
  488.     nw.CheckMark = NULL;
  489.     nw.Screen = S;
  490.     nw.BitMap = NULL;
  491.     if ((W = (struct Window *) OpenWindow(&nw)) == NULL) exit(1);
  492.     R = W->RPort;
  493.     SetAPen(R, ORANGE);
  494.     SetBPen(R, BLACK);
  495.     ShowTitle(S, FALSE);
  496.     Cols=80;
  497.     Rows=24;
  498. #ifdef ARP
  499.     MyFileRequest.fr_Window = W;
  500. #endif
  501. }
  502.  
  503. windgoto(r,c)
  504. int r,c;
  505. {
  506.     Move(R, c*8, r*8 + R->Font->tf_Baseline);
  507. }
  508.  
  509. windeeol()
  510. {
  511.     int x, y;
  512.     x = R->cp_x;
  513.     y = R->cp_y  - R->Font->tf_Baseline;
  514.     SetAPen(R, BLACK);
  515.     RectFill(R, x, y, WindowWidth, y+R->Font->tf_YSize-1);
  516.     SetAPen(R, ORANGE);
  517. }
  518.  
  519. winderaserow(r)
  520. {
  521.     windgoto(r,0);
  522.     windeeol();
  523. }
  524.  
  525. windexit(r)
  526. int r;
  527. {
  528. #ifdef ARP
  529.     if (W) CloseWindowSafely(W,NULL);
  530. #else
  531.     if (W) CloseWindow(W);
  532. #endif
  533.     if (S) CloseScreen(S);
  534.     exit(r);
  535. }
  536.  
  537. windclear()
  538. {
  539.     SetAPen(R, BLACK);
  540.     RectFill(R, 0, 0, WindowWidth, WindowHeight);
  541.     SetAPen(R, ORANGE);
  542. }
  543.  
  544. /* windgets - get a line of input from the console, handling backspaces */
  545. windgets(s)
  546. char *s;
  547. {
  548.     char *origs = s;
  549.     int c;
  550.  
  551. #ifdef ARP
  552.     if (FileRequestImminent) {
  553.         FileRequestImminent = FALSE;
  554.         if (FileRequest(&MyFileRequest)==NULL) {
  555.                   message("No file name entered");
  556.             strcpy(s,"");
  557.               }   
  558.         else {
  559.             strcpy(s,DirName);
  560.             if(s[0]!=0 && (s[strlen(s)-1]!=':'))
  561.                 strcat(s,"/");
  562.             strcat(s,FileName);
  563.         }
  564.     }
  565.     else {
  566. #endif
  567.     SetAPen(R, WHITE);
  568.  
  569.     while ( (c=getconsole()) != '\n' && c!='\r' && c!= EOF ) {
  570.         if ( c == '\b' ) {
  571.             if ( s > origs ) {
  572.                 wbackspace();
  573.                 s--;
  574.             }
  575.         }
  576.         else if (c == 24) {
  577.             while (s > origs) {
  578.                 wbackspace();
  579.                 s--;
  580.             }
  581.         } else if (isprint(c)) {
  582.             windputc(c);
  583.             *s++ = c;
  584.         }
  585.         windrefresh();
  586.     }
  587.     *s = '\0';
  588.     SetAPen(R, ORANGE);
  589. #ifdef ARP
  590.     }
  591. #endif
  592. }
  593.  
  594. windstr(s)
  595. char *s;
  596. {
  597. #ifdef ARP
  598.     if (!strnicmp(s,"File name",9))
  599.         FileRequestImminent = TRUE;
  600.     else
  601. #endif
  602.  
  603.         Text(R, s, strlen(s));
  604. }
  605.  
  606. windputc(c)
  607. int c;
  608. {
  609.     char s = c;
  610.     Text(R, &s, 1);
  611. }
  612.  
  613. wbackspace()
  614. {
  615.     int x, y;
  616.     x = R->cp_x;
  617.     y = R->cp_y;
  618.     Move(R, x-8, y);
  619.     windputc(' ');
  620.     Move(R, x-8, y);
  621. }
  622.  
  623. windrefresh()
  624. {
  625. }
  626.  
  627. beep()
  628. {
  629.     DisplayBeep(S);
  630. }
  631.  
  632. windhigh()
  633. {
  634. }
  635.  
  636. windnorm()
  637. {
  638. }
  639.  
  640. struct IntuiText fataltext = { 1,0,COMPLEMENT,16,32,NULL,NULL,NULL };
  641. struct IntuiText canceltext = { 1,0,COMPLEMENT,2,2,NULL,"cancel",NULL };
  642.  
  643. fatal(text)
  644. char *text;
  645. {
  646.     fataltext.IText = text;
  647.     AutoRequest(W, &fataltext, NULL, &canceltext, 0, 0, 320, 90);
  648.     bye();
  649. }
  650.  
  651. /****************
  652.  * openls(), nextls(), and closels() are used to scan the current directory.
  653.  ***************/
  654.  
  655. #ifdef AZTEC_C
  656. #include "amigadir.h"
  657. static DIR *dir;
  658. openls()
  659. {
  660.     dir = opendir("");
  661. }
  662. char *
  663. nextls()
  664. {
  665.     struct direct *result;
  666.  
  667.     if (dir) {
  668.         if (result = readdir(dir)) {
  669.             return result->d_name;
  670.         }
  671.         closels();
  672.     }
  673.     return NULL;
  674. }
  675.  
  676. closels()
  677. {
  678.     if (dir) {
  679.         closedir(dir);
  680.         dir = NULL;
  681.     }
  682. }
  683. #else
  684. struct FileInfoBlock *lsinfo = NULL;
  685.  
  686. openls()
  687. {
  688. }
  689.  
  690. char *
  691. nextls()
  692. {
  693.     int error;
  694.     if (lsinfo == NULL) {
  695.         lsinfo = (struct FileInfoBlock *) alloc(sizeof(struct FileInfoBlock));
  696.         error = dfind(lsinfo, "#?", 0);
  697.     } else {
  698.         error = dnext(lsinfo);
  699.     }
  700.     if (error == 0) {
  701.         return lsinfo->fib_FileName;
  702.     } else {
  703.         return NULL;
  704.     }
  705. }
  706.  
  707. closels()
  708. {
  709.     free(lsinfo);
  710.     lsinfo = NULL;
  711. }
  712. #endif
  713.  
  714.