home *** CD-ROM | disk | FTP | other *** search
/ Vectronix 2 / VECTRONIX2.iso / FILES_07 / ACS.ZIP / ACS / PIANO / PIANO.C < prev    next >
C/C++ Source or Header  |  1992-01-28  |  5KB  |  218 lines

  1. /*
  2.     Beispielapplikation für ACS
  3.  
  4.     "Piano"
  5.  
  6.     14.1.92         Stefan Bachert
  7.  
  8. */
  9.  
  10. #include    <tos.h>
  11. #include    <acs.h>
  12. #include    <piano.h>
  13.  
  14. /* Prototypen anlegen */
  15.  
  16. static void ton (void);
  17. static void start (void);
  18. static void play (void);
  19. static Awindow *piano_make (void *not_used);
  20. static int piano_service (Awindow *window, int task, void *in_out);
  21.  
  22. #include    <piano.ah>
  23.  
  24. #define MAXSOUND 200
  25.  
  26. typedef struct {
  27.     int key;
  28.     long time;
  29.     } single;
  30. typedef struct {
  31.     int next;
  32.     single field [MAXSOUND];
  33.     } tape;
  34.  
  35. /* Soundgenerator ansteuern */
  36. static char sound [] = {
  37.     0x00, 0x10,                /* Generator A Frequenz einstellen */
  38.     0x01, 0x10,
  39.     0x07, 0xf8,                /* Rauschen ausschalten */
  40.     0x0b, 0x00,                /* Tonlänge Hüllkurve */
  41.     0x0c, 0x30,
  42.     0x08, 0x17,                /* Lautstärke */
  43.     0x0d, 0x00,                /* Hüllkurve abklingend */
  44.     0xff, 0x00                /* stop */
  45.     };
  46.  
  47. static long timer_200Hz (void)
  48. {
  49.   return *((long *) 0x4BA);        /* holt 200Hz Timer */
  50. }
  51.  
  52. static void ton (void)
  53.     /*
  54.      *    lä₧t ton der Frequenz (userp1) / 1000 ertönen
  55.      *    
  56.      */
  57. {
  58.   AOBJECT *aob;
  59.   int next;
  60.   long val, timer;
  61.   tape *user;
  62.  
  63.   aob = (AOBJECT *) ev_object + ev_obnr + 1;
  64.   val = 125000000L / (long) aob-> userp1;    /* berechne Teilerwert */
  65.  
  66.   sound [1] = (char) val;                /* unteres Byte */
  67.   sound [3] = (char) (val >> 8) & 0x0f; /* oberes (Halb) Byte */
  68.  
  69.   timer = Supexec (timer_200Hz);        /* merke Zeitpunkt */
  70.   Dosound (sound);
  71.   evnt_timer (80, 0);        /*  x Milli Sec warten (visuelle Rückmeldung) */
  72.  
  73. /*    aufzeichnen */
  74.   user = ev_window-> user;
  75.   next = user-> next ++;
  76.   if (next >= MAXSOUND) return;    /* tape voll */
  77.   user-> field [next]. key = ev_obnr;
  78.   user-> field [next]. time= timer;
  79. }
  80.  
  81. static void start (void)
  82.     /*
  83.      *    Beginnt am Anfang mit dem Aufzeichnen, Löschen !
  84.      */
  85. {
  86.   tape *user;
  87.  
  88.   user = ev_window-> user;
  89.   user-> next = 0;
  90. }
  91.  
  92.  
  93. static void play (void)
  94.     /*
  95.      *    Spielt Band ab
  96.      */
  97.   Awindow *window;
  98.   OBJECT *work;
  99.   AOBJECT *aob;
  100.   tape *user;
  101.   long st_time, nxt_time, val;
  102.   int act, key;
  103.   int t, button;
  104.  
  105.   window = ev_window;
  106.   work = ev_object;
  107.  
  108.   user = window-> user;
  109.  
  110.   st_time = Supexec (timer_200Hz) - user-> field-> time;    /* erste Zeit überspringen */
  111.  
  112.   for (act = 0; act < user-> next; act ++) {
  113.     nxt_time = st_time + user-> field [act]. time;
  114.     while (Supexec (timer_200Hz) < nxt_time) {
  115.       graf_mkstate (&t, &t, &button, &t);    /* abbruch Maustaste */
  116.       if (button != 0) break;    
  117.     };    /* warte */
  118.  
  119.     key = user-> field [act]. key;
  120.     aob = (AOBJECT *) work + key + 1;
  121.     val = 125000000L / (long) aob-> userp1;    /* berechne Teilerwert */
  122.     sound [1] = (char) val    ;                /* unteres Byte */
  123.     sound [3] = (char) (val >> 8) & 0x0f; /* oberes (Halb) Byte */
  124.  
  125.     (window-> obchange) (window, key, work [key]. ob_state | SELECTED);
  126.     Dosound (sound);
  127.     evnt_timer (80, 0);        /*  x Milli Sec warten (visuelle Rückmeldung) */
  128.     (window-> obchange) (window, key, work [key]. ob_state & ~SELECTED);
  129.  
  130.     graf_mkstate (&t, &t, &button, &t);    /* abbruch Maustaste*/
  131.     if (button != 0) break;    
  132.   };
  133. }
  134.  
  135.  
  136. static Awindow *piano_make (void *not_used)
  137.     /*
  138.      *  Erzeuge Piano Fenster
  139.      */
  140. {
  141.   Awindow *wi;
  142.   tape *user;
  143.  
  144.   wi = Awi_create (&PIANO);
  145.   if (wi == NULL) return NULL;
  146.  
  147.   user =
  148.   wi-> user = Ax_malloc (sizeof (tape));    /* Datenstruktur anlegen */
  149.   if (user == NULL) return NULL;            /* Fehler passiert */
  150.  
  151.   user-> next = 0;                             /* Initialisieren */
  152.  
  153.   if (application) {
  154.     (wi-> open) (wi);                        /* öffne gleich */
  155.   };
  156.   return wi;
  157. }
  158.  
  159.  
  160. static int piano_service (Awindow *window, int task, void *in_out)
  161. {
  162.   switch (task) {
  163.     case AS_TERM:                    /* Fenster freigeben */
  164.       Ax_free (window-> user);        /* Struktur freigeben */
  165.       Awi_delete (window); break;
  166.     default:
  167.       return FAIL;
  168.   };
  169.   return TRUE;
  170. }
  171.  
  172.  
  173. static char oldconterm;    /* für ursprünglichen Wert */
  174.  
  175. static long off_click (void)
  176. {
  177.   oldconterm = *((char *) 0x484);
  178.   *((char *) 0x484) &= ~3;        /* kein click und keine Tastenwiederholung */
  179.   return 0L;
  180. }
  181.  
  182.  
  183. static long old_click (void)
  184. {
  185.   *((char *) 0x484) = oldconterm;
  186.   return 0L;
  187. }
  188.  
  189.  
  190. void ACSterm (void)
  191. {
  192.   Supexec (old_click);                    /* alter Zustand */
  193. }
  194.  
  195.  
  196. int ACSinit (void)
  197.     /*
  198.      *  Doppelklick auf NEU erzeugt ein neues Fenster
  199.      */
  200. {
  201.   Awindow *window;
  202.  
  203.   Supexec (off_click);                    /* click ausschalten */
  204.  
  205.   if (application) {
  206.     window = Awi_root ();                 /* root window */
  207.  
  208.     if (window == NULL) return FAIL;      /* lege NEU Icon an */
  209.     (window-> service) (window, AS_NEWCALL, &PIANO. create);
  210.  
  211.     window = &PIANO;
  212.     (window-> create) (NULL);             /* sofort ein Fenster erzeugen */
  213.   };
  214.  
  215.   return OK;
  216. }
  217.