home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d7xx / d787 / scale.lha / Scale / Source.lha / scale.c < prev    next >
C/C++ Source or Header  |  1992-12-12  |  29KB  |  1,008 lines

  1. /* Program Scale.c   Play 1 to 4 simultaneous independent scales */
  2.  
  3. /*        ==> RECOMMENDED <== */
  4. /*        Set tab interval to 3 for listing of this code */
  5.  
  6. /* Programmer: Dick Taylor      November 1992 */
  7. /*             99 Valley View Rd, Glastonbury CT 06033 USA */
  8.  
  9. /* Please refer to file scale.doc for usage & programming background. */
  10.  
  11. #include <exec/types.h>
  12. #include <intuition/intuition.h>
  13. #include <stdio.h>
  14. #include <graphics/gfxbase.h>
  15.  
  16. /* These constants are used in constructing the user interface. */
  17. #define KGX 390
  18. #define KGY 120
  19. #define TGX 390
  20. #define TGY 148
  21. #define AGX 30
  22. #define AGY 128
  23. #define CIN 20
  24. #define CGY 27
  25. #define ADX 94
  26. #define CTX 104
  27. #define CYXI 150
  28. #define ZX -55
  29. #define GG 60
  30. #define PGX 420
  31. #define PGY 180
  32.  
  33. /*#include modified "FileWindow.h" -- 9 lines inserted */
  34. /* What file_window() will return: */
  35. #define LOAD    500
  36. #define SAVE    600
  37. #define CANCEL  800
  38. #define QUIT    900
  39. #define PANIC1  1001        /* Cannot open window for FileWindow */
  40. #define PANIC2  1002        /* Not enough memory */
  41.  
  42. /* The minimum size of the total file name string -- Drawer + File: */
  43. #define TOTAL_LENGTH  130 /*  130 char's incl NULL */
  44.  
  45. /* THE END -- of modified FileWindow.h */
  46.  
  47. struct IntuitionBase *IntuitionBase;
  48. struct GfxBase *GfxBase;
  49. extern int help();
  50. extern USHORT FileWindow();
  51. extern void PlayScale();
  52.  
  53.     /* Box for 1-char gadget */
  54. /*SHORT c1_box[] = {0,0,  15,0,  15,10,  0,10,  0,0};
  55. struct Border c1_border = {0,0,1,0,JAM1,5,c1_box,NULL};*/
  56.  
  57.     /* Box for 2-char gadget (also used for 1 char) */
  58. SHORT c2_box[] = {0,0,  23,0,  23,10,  0,10,  0,0};
  59. struct Border c2_border = {0,0,1,0,JAM1,5,c2_box,NULL};
  60.  
  61.     /* Box for 3-char gadget */
  62. SHORT c3_box[] = {0,0,  39,0,  39,10,  0,10,  0,0};
  63. struct Border c3_border = {0,0,1,0,JAM1,5,c3_box,NULL};
  64.  
  65.     /* Box for 4-char gadget */
  66. SHORT c4_box[] = {0,0,  79,0,  79,14,  0,14,  0,0};
  67. struct Border c4_border = {0,0,1,0,JAM1,5,c4_box,NULL};
  68.  
  69.     /* Box for 6-char gadget */
  70. SHORT c6_box[] = {0,0,  59,0,  59,10,  0,10,  0,0};
  71. struct Border c6_border = {0,0,1,0,JAM1,5,c6_box,NULL};
  72.  
  73.     /* Box for ADR Edit */
  74. SHORT ad_box[] = {-10,-5,  160,-5,  160,32,  -10,32,  -10,-5};
  75. struct Border ad_border = {0,0,1,0,JAM1,5,ad_box,&c2_border};
  76.  
  77.     /* Grid to enclose channel settings */
  78. SHORT grid[] = {ZX,93, ZX,0,  570,0,  570,93,  ZX,93,  0,93,  0,0,
  79.     50,0,  50,93,  76,93,  76,0,  102,0,  102,93,  144,93,  144,0,
  80.     ZX,0,  ZX,13,  570,13,  570,33,  ZX,33,  ZX,53,  570,53, 570,73, ZX,73 };
  81. struct Border g_border = {GG,14,1,0,JAM1,24,grid,NULL};
  82.  
  83. struct IntuiText stext_request = {0,2,JAM1,15,5,NULL,NULL,NULL};
  84. struct IntuiText sok_request = {0,2,JAM1,6,3,NULL,"OK",NULL};
  85.  
  86.     /* Channel 0 gadget */
  87. struct Gadget ch0_gadget = {NULL,GG,CGY,50,20,GADGHCOMP,
  88.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  89.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  90.  
  91.     /* Channel 1 gadget */
  92. struct Gadget ch1_gadget = {&ch0_gadget,GG,CGY+20,50,20,GADGHCOMP,
  93.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  94.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  95.  
  96.     /* Channel 2 gadget */
  97. struct Gadget ch2_gadget = {&ch1_gadget,GG,CGY+40,50,20,GADGHCOMP,
  98.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  99.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  100.  
  101.     /* Channel 3 gadget */
  102. struct Gadget ch3_gadget = {&ch2_gadget,GG,CGY+60,50,20,GADGHCOMP,
  103.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  104.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  105.  
  106.     /* Key gadget */
  107. struct IntuiText key_tex = {1,0,JAM1,-34,2,NULL,"Key:",NULL};
  108. struct Gadget key_gadget = {&ch3_gadget, KGX,KGY,24,11,GADGHCOMP,
  109.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  110.         &c2_border,NULL,&key_tex,NULL,NULL,0,NULL};
  111.  
  112.     /* Key2 gadget -- #, b, _ (sharp, flat, or neither) */
  113. struct Gadget key2_gadget = {&key_gadget, KGX+30,KGY,24,11,GADGHCOMP,
  114.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  115.         &c2_border,NULL,NULL,NULL,NULL,0,NULL};
  116.  
  117.     /* Cycle gadget */
  118. struct IntuiText cycle_tex = {1,0,JAM1,-44,2,NULL,"Cycle",NULL};
  119. struct Gadget cycle_gadget = {&key2_gadget, KGX+CYXI,KGY,24,11,GADGHCOMP,
  120.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  121.         &c2_border,NULL,&cycle_tex,NULL,NULL,0,NULL};
  122.  
  123.     /* Clear channel gadget */
  124. struct Gadget clear_gadget = {&cycle_gadget,GG+ZX,27,55,80,GADGHCOMP,
  125.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  126.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  127.  
  128.     /* Note gadget */
  129. struct Gadget note_gadget = {&clear_gadget,GG+50,27,26,80,GADGHCOMP,
  130.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  131.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  132.  
  133.     /* Octave gadget */
  134. struct Gadget oct_gadget = {¬e_gadget,GG+76,27,26,80,GADGHCOMP,
  135.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  136.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  137.  
  138.     /* TimeValue gadget */
  139. struct Gadget time_gadget = {&oct_gadget,GG+102,27,42,80,GADGHCOMP,
  140.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  141.         NULL,NULL,NULL,NULL,NULL,0,NULL};
  142.  
  143.     /* Left AD Edit gadget */
  144. UBYTE lad_char = '<';
  145. struct IntuiText lad_tex1 = {1,0,JAM1,44,-14,NULL,"ADR+ Edit",NULL};
  146. struct IntuiText lad_tex2 = {1,0,JAM1,8,2,NULL,&lad_char,&lad_tex1};
  147. struct Gadget lad_gadget = {&time_gadget, AGX,AGY,24,11,GADGHCOMP,
  148.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  149.         &ad_border,NULL,&lad_tex2,NULL,NULL,0,NULL};
  150.  
  151.     /* Right AD Edit gadget */
  152. UBYTE rad_char = '>';
  153. struct IntuiText rad_tex = {1,0,JAM1,8,2,NULL,&rad_char,NULL};
  154. struct Gadget rad_gadget = {&lad_gadget, AGX+30,AGY,24,11,GADGHCOMP,
  155.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  156.         &c2_border,NULL,&rad_tex,NULL,NULL,0,NULL};
  157.  
  158.     /* Ascend/Descend/Rest/Repeat (ADR+) Edit gadget */
  159. struct IntuiText adr_tex = {1,0,JAM1,5,2,NULL,"ADR+",NULL};
  160. struct Gadget adr_gadget = {&rad_gadget, AGX+60,AGY,40,11,GADGHCOMP,
  161.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  162.         &c3_border,NULL,&adr_tex,NULL,NULL,0,NULL};
  163.  
  164.     /* Count ADR Edit gadget */
  165. struct IntuiText cad_tex = {1,0,JAM1,8,2,NULL,"1-4",NULL};
  166. struct Gadget cad_gadget = {&adr_gadget, AGX+110,AGY,40,11,GADGHCOMP,
  167.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  168.         &c3_border,NULL,&cad_tex,NULL,NULL,0,NULL};
  169.  
  170.     /* Insert AD Edit gadget */
  171. struct IntuiText ins_tex = {1,0,JAM1,5,2,NULL,"Insert",NULL};
  172. struct Gadget ins_gadget = {&cad_gadget, AGX,AGY+15,60,11,GADGHCOMP,
  173.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  174.         &c6_border,NULL,&ins_tex,NULL,NULL,0,NULL};
  175.  
  176.     /* Delete AD Edit gadget */
  177. struct IntuiText dad_tex = {1,0,JAM1,5,2,NULL,"Delete",NULL};
  178. struct Gadget dad_gadget = {&ins_gadget, AGX+80,AGY+15,60,11,GADGHCOMP,
  179.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  180.         &c6_border,NULL,&dad_tex,NULL,NULL,0,NULL};
  181.  
  182.     /* Tempo gadget (proportional) */
  183. struct IntuiText tempo_tex1 = {1,0,JAM1,46,-9,NULL,"Tempo=",NULL};
  184. struct IntuiText tempo_tex2 = {1,0,JAM1,-15,-9,NULL,"Slow",&tempo_tex1};
  185. struct IntuiText tempo_tex3 = {1,0,JAM1,185,-9,NULL,"Fast",&tempo_tex2};
  186. struct Image tempo_image;
  187. struct PropInfo tempo_info = {FREEHORIZ | AUTOKNOB,0,0,
  188.         MAXBODY * 1/400, 0,0,0,0,0,0,0};
  189. struct Gadget tempo_gadget = {&dad_gadget,TGX,TGY,200,12,GADGHCOMP,
  190.         GADGIMMEDIATE | RELVERIFY, PROPGADGET,
  191.         &tempo_image,NULL,&tempo_tex3,NULL,&tempo_info,0,NULL};
  192.  
  193.     /* Play gadget */
  194. struct IntuiText play_tex = {3,0,JAM1,4,4,NULL,"PLAY",NULL};
  195. struct Gadget play_gadget = {&tempo_gadget,PGX,PGY,80,15,GADGHCOMP,
  196.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  197.         &c4_border,NULL,&play_tex,NULL,NULL,0,NULL};
  198.  
  199.     /* Stop gadget */
  200. struct IntuiText stop_tex = {2,3,JAM2,4,4,NULL,"STOP Play",NULL};
  201. struct Gadget stop_gadget = {NULL,PGX,PGY,80,15,GADGHCOMP,
  202.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  203.         &c4_border,NULL,&stop_tex,NULL,NULL,0,NULL};
  204.  
  205.     /* Quit gadget */
  206. struct IntuiText quit_tex = {3,0,JAM1,20,4,NULL,"QUIT",NULL};
  207. struct Gadget quit_gadget = {&play_gadget,PGX+100,PGY,80,15,GADGHCOMP,
  208.         GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  209.         &c4_border,NULL,&quit_tex,NULL,NULL,0,NULL};
  210.  
  211.     /* 5th menu item */
  212. struct IntuiText mtext5 = {2,0,JAM1,0,1,NULL,"Quit",NULL};
  213. struct MenuItem mitem5 = {NULL,0,40,150,10,
  214.         ITEMTEXT | ITEMENABLED | HIGHCOMP,0,&mtext5,NULL,0,NULL,MENUNULL};
  215.  
  216.     /* 4th menu item */
  217. struct IntuiText mtext4 = {2,0,JAM1,0,1,NULL,"About",NULL};
  218. struct MenuItem mitem4 = {&mitem5,0,30,150,10,
  219.         ITEMTEXT | ITEMENABLED | HIGHCOMP,0,&mtext4,NULL,0,NULL,MENUNULL};
  220.  
  221.     /* 3rd menu item */
  222. struct IntuiText mtext3 = {2,0,JAM1,0,1,NULL,"Save",NULL};
  223. struct MenuItem mitem3 = {&mitem4,0,20,150,10,
  224.         ITEMTEXT | ITEMENABLED | HIGHCOMP,0,&mtext3,NULL,0,NULL,MENUNULL};
  225.  
  226.     /* 2nd menu item */
  227. struct IntuiText mtext2 = {2,0,JAM1,0,1,NULL,"Load",NULL};
  228. struct MenuItem mitem2 = {&mitem3,0,10,150,10,
  229.         ITEMTEXT | ITEMENABLED | HIGHCOMP,0,&mtext2,NULL,0,NULL,MENUNULL};
  230.  
  231.     /* 1st menu item */
  232. struct IntuiText mtext1 = {2,0,JAM1,0,1,NULL,"Help",NULL};
  233. struct MenuItem mitem1 = {&mitem2,0,0,150,10,
  234.         ITEMTEXT | ITEMENABLED | HIGHCOMP,0,&mtext1,NULL,0,NULL,MENUNULL};
  235.  
  236.     /* The menu (only 1) */
  237. struct Menu smenu = {NULL,0,0,50,0,MENUENABLED,"Project",&mitem1};
  238.  
  239. struct MenuItem *item;
  240.  
  241.     /* ABOUT Requester */
  242. #define BOXW  80        /* Req gadget box width */
  243. #define BOXH  15        /* Req gadget box height */
  244.  
  245.         /* Use boxR1 for About Req gadget */
  246. SHORT boxR1[] = {0,0,  BOXW-1,0,  BOXW-1,BOXH-1,  0,BOXH-1,  0,0};
  247.  
  248. struct Border borderR1 = {0,0,1,0,JAM1,5,boxR1,NULL};
  249.         /* About Reqester -- OK gadget structures */
  250.  
  251. struct IntuiText ok_text = {1,0,JAM1,25,4,NULL,"OK",NULL};
  252.  
  253. struct Gadget ok_gadget =
  254.     {    NULL,25,70,BOXW,BOXH,GADGHCOMP,
  255.         GADGIMMEDIATE | RELVERIFY | ENDGADGET,
  256.         BOOLGADGET | REQGADGET,
  257.         &borderR1,NULL,&ok_text,NULL,NULL,0,NULL};
  258.  
  259.         /* About Requester structures */
  260.  
  261. SHORT areq_box[] = {0,0,  599,0,  599,99,  0,99,  0,0};
  262.  
  263. struct Border areq_border = {0,0,1,0,JAM1,5,areq_box,NULL,};
  264.  
  265. struct IntuiText areq_tex1 = {2,3,JAM2,100,8,NULL,
  266.         "SCALE Program by --",NULL,};
  267. struct IntuiText areq_tex2 = {2,3,JAM2,50,26,NULL,
  268.         "Dick Taylor   Tel (203) 633-0100",&areq_tex1,};
  269. struct IntuiText areq_tex3 = {2,3,JAM2,80,38,NULL,
  270.         "99 Valley View Road",&areq_tex2,};
  271. struct IntuiText areq_tex4 = {2,3,JAM2,50,50,NULL,
  272.         "Glastonbury Connecticut 06033 USA",&areq_tex3,};
  273.  
  274. struct Requester areq =
  275.     {    NULL,10,20,600,100,0,0,&ok_gadget,&areq_border,&areq_tex4,
  276.         NULL,2,NULL,NULL,NULL,NULL,NULL};
  277.  
  278. struct IntuiText sp_text = {1,0,JAM2,0,0,NULL,"           ",NULL};
  279.  
  280. struct Window *w;
  281. struct NewWindow nw = {0,0,640,200,0,1, CLOSEWINDOW | GADGETUP | MENUPICK,
  282.         SMART_REFRESH | WINDOWCLOSE | 
  283.         WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING | ACTIVATE, &quit_gadget,NULL,
  284.         "SCALE",NULL,NULL,140,50,640,200,WBENCHSCREEN};
  285.  
  286. struct IntuiMessage *msg;
  287.  
  288. char Key,Key2,Note[4], TimeV[4], cyc = 'N',ktext[2],ttext[4],PrevChar;
  289. int  Octave[4], Tempo=500,
  290.     TicksPerSec;    /* Clock ticks/second -- NTSC (American) = 3579545 */
  291.                         /* or PAL (European) = 3546895 */
  292. struct            /* Ascend/Descend/Rest structure */
  293. {
  294.     char ad[15];    /* For each of 4 channels, we have */
  295.     int  ct[15];    /* 15 pairs of A/D/R/+ and count; 14 are usable */
  296. }    zChan[4];
  297. BOOL fin = FALSE, cycle = FALSE;
  298.  
  299. int c,        /* Current channel = 0, 1, 2, or 3 */
  300.     kAD[4],    /* No. of ad/ct entries, per chan; 0 - 14 */
  301.     yULine = 0,    /* y-offset for drawing 'ADR+' underline */
  302.     iAD = 0;    /* For current chan, position in ad/ct array of zChan; 0-13 */
  303. char ptext[6];
  304. struct IntuiText int_text = {1,0,JAM1,GG+60,32,NULL,ptext,NULL};
  305. struct IntuiText tv_text = {1,0,JAM1,GG+112,32,NULL,"1/",NULL};
  306. struct IntuiText uln_text = {1,0,JAM1,GG+154,40,NULL,"^^",NULL};
  307. struct IntuiText ky_text = {1,0,JAM1,KGX+8,KGY+2,NULL,NULL,NULL};
  308.  struct IntuiText tp_text = {1,0,JAM1,TGX+100,TGY-9,NULL,NULL,NULL};
  309.  char ctex[3];
  310.  struct IntuiText cal_text = {1,0,JAM1,TGX-8,TGY+20,NULL,ctex,NULL};
  311.  SHORT cal[] = {0,0,  0,5,  1,5,  1,0,  2,0,  2,5};
  312.  struct Border calborder = {TGX,TGY+12,1,0,JAM1,6,cal,NULL};
  313.  
  314.  
  315. main()
  316. {
  317.  ULONG class;
  318.  USHORT code, menu_number;
  319.  struct Gadget *address;
  320.  int  val, i,j;
  321.  char a;
  322.  BOOL result;
  323.  
  324.  ctex[0] = '.'; ctex[2] = '\0';
  325.  Key = 'C'; Key2 = '_';
  326.  Note[0] = 'C';        /* Init chan 0 to middle C scale, ascend */
  327.  Octave[0] = 4;
  328.  TimeV[0] = '1';
  329.  for (i = 1; i < 15; ++i)
  330.  {
  331.     zChan[0].ad[i] = ' ';
  332.     zChan[0].ct[i] = 0;
  333.  }
  334.  zChan[0].ad[0] = 'A';
  335.  zChan[0].ct[0] = 1;
  336.  kAD[0] = 1;
  337.  for (i = 1; i < 4; ++i)    /* Init chan's 1-3 to not play */
  338.  {
  339.     Note[i] = ' ';
  340.     Octave[i] = 0;
  341.     TimeV[i] = ' ';
  342.     for (j = 0; j < 15; ++j)
  343.     {
  344.         zChan[i].ad[j] = ' ';
  345.         zChan[i].ct[j] = 0;
  346.     }
  347.     kAD[i] = 0;
  348.  }
  349.  ktext[1] = '\0';
  350.  strcpy (ttext,".50");
  351.  tp_text.IText = ttext;
  352.  ky_text.IText = ktext;
  353.  
  354.  IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0);
  355.  if (IntuitionBase == NULL)
  356.     {printf ("Module scale error--can't open Intuition, exit.\n");  exit(1); }
  357.  
  358.  w = (struct Window *) OpenWindow(&nw);
  359.  if (w == NULL)
  360.  {    printf ("Module scale error--can't open Window, exit.\n");
  361.     CloseLibrary(IntuitionBase);
  362.     exit(2);
  363.  }
  364.  
  365.  InitWindow();        /* Check for NTSC (American) or PAL (European), */
  366.                         /* Initialize window display:  draw grid, enter text, */
  367.                         /* initialize menu */
  368.  
  369.  while (!fin)
  370.  {                                    /* Wait for user input -- menu or gadgets */
  371.  
  372.     Wait(1 << w->UserPort->mp_SigBit);
  373.     while (msg = (struct IntuiMessage *) GetMsg(w->UserPort))
  374.     {
  375.         class = msg->Class;
  376.         address = msg->IAddress;
  377.         code = msg->Code;
  378.         ReplyMsg(msg);
  379.  
  380.         switch(class)
  381.         {
  382.             case CLOSEWINDOW:
  383.                 fin = TRUE;
  384.                 break;
  385.             case MENUPICK:
  386.                 menu_number = code;
  387.                 while (menu_number != MENUNULL)
  388.                 {
  389.                     item = (struct MenuItem *) ItemAddress(&smenu,menu_number);
  390.                     if (item == &mitem1)                /* Help */
  391.                         help();
  392.                     else if (item == &mitem2 ||    /* Load */
  393.                                item == &mitem3)        /* Save */
  394.                         UseFileWindow();
  395.                     else if (item == &mitem4)        /* About */
  396.                     {
  397.                         result = Request(&areq,w);
  398.                         if (result)
  399.                         {
  400.                             Wait(1 << w->UserPort->mp_SigBit);
  401.                             while (msg = (struct IntuiMessage *) GetMsg(w->UserPort))
  402.                             ReplyMsg(msg);                /* Clean out messages & finish up */
  403.                         }
  404.                         else
  405.                         {
  406.                             printf("Can't activate About requester.\n");
  407.                         }
  408.                     }
  409.                     else if (item == &mitem5)        /* Quit */
  410.                         fin = TRUE;
  411.                     menu_number = item->NextSelect;
  412.                 }
  413.                 break;
  414.             case GADGETUP:
  415.                 if (address == &quit_gadget)                /* Quit gadget */
  416.                     fin = TRUE;
  417.                 else if (address == &play_gadget)        /* Play gadget */
  418.                 {
  419.                     RemoveGadget(w,&play_gadget);
  420.                     PrintIText(w->RPort,&sp_text,420,PGY);    /* Erase PLAY */
  421.                     PrintIText(w->RPort,&sp_text,420,PGY+8);    /* Erase PLAY */
  422.                     AddGadget(w,&stop_gadget,-1);
  423.                     RefreshGadgets(&quit_gadget,w,NULL);
  424.                     PlayScale();
  425.                     RemoveGadget(w,&stop_gadget);
  426.                     PrintIText(w->RPort,&sp_text,420,PGY);    /* Erase STOP */
  427.                     PrintIText(w->RPort,&sp_text,420,PGY+8);    /* Erase STOP */
  428.                     AddGadget(w,&play_gadget,-1);
  429.                     RefreshGadgets(&quit_gadget,w,NULL);
  430.                 }
  431.                 else if (address == &ch0_gadget)        /* Chan 0 gadget */
  432.                 {    c = 0;    yULine = 0; iAD = 0;    
  433.                     if (Note[0] == ' ') InitChan();    /* Init Chan 0 */
  434.                     else ULine(0,0);
  435.                 }
  436.                 else if (address == &ch1_gadget)        /* Chan 1 gadget */
  437.                 {    c = 1;    yULine = CIN; iAD = 0;
  438.                     if (Note[c] == ' ') InitChan();    /* Init Chan 1 */
  439.                     else ULine(0,yULine);
  440.                 }
  441.                 else if (address == &ch2_gadget)        /* Chan 2 gadget */
  442.                 {    c = 2;    yULine = 2*CIN; iAD = 0;
  443.                     if (Note[c] == ' ') InitChan();    /* Init Chan 2 */
  444.                     else ULine(0,yULine);
  445.                 }
  446.                 else if (address == &ch3_gadget)        /* Chan 3 gadget */
  447.                 {    c = 3;    yULine = 3*CIN; iAD = 0;
  448.                     if (Note[c] == ' ') InitChan();    /* Init Chan 3 */
  449.                     else ULine(0,yULine);
  450.                 }
  451.                 else if (address == &key_gadget)        /* Key gadget */
  452.                 {
  453.                     if (Key2 != '_')
  454.                     {    PrevChar = Key2;
  455.                         Key2 = '_';
  456.                         ErasWriteA(PrevChar,Key2,30,0);
  457.                     }
  458.                     PrevChar = Key;
  459.                     Key += 1;
  460.                     if (Key > 'G') Key = 'A';
  461.                     ErasWriteA(PrevChar,Key,0,0);
  462.                 }
  463.                 else if (address == &key2_gadget)    /* _#b gadget */
  464.                 {
  465.                     PrevChar = Key2;
  466.                     if (Key2 == '_')
  467.                     {    Key2 = '#';
  468.                         if (Key == 'B' || Key == 'E') Key2 = 'b';
  469.                     }
  470.                     else if (Key2 == '#')
  471.                     {    Key2 = 'b';
  472.                         if (Key == 'C' || Key == 'F') Key2 = '_';
  473.                     }
  474.                     else Key2 = '_';
  475.                     ErasWriteA(PrevChar,Key2,30,0);
  476.                 }
  477.                 else if (address == &cycle_gadget)    /* Cycle gadget */
  478.                 {
  479.                     PrevChar = cyc;
  480.                     if (cycle) {cycle = FALSE; cyc = 'N';}
  481.                     else       {cycle = TRUE;  cyc = 'Y';}
  482.                     ErasWriteA(PrevChar,cyc,CYXI,0);
  483.                 }
  484.                 else if (address == &clear_gadget)    /* Clear gadget */
  485.                 {
  486.                     ErasWriteB(Note[c],' ',0,yULine);
  487.                     ErasWriteB(Octave[c]+'0',' ',25,yULine);
  488.                     tv_text.FrontPen = 0;
  489.                     PrintIText(w->RPort,&tv_text,0,yULine);
  490.                     tv_text.FrontPen = 1;
  491.                     ErasWriteB(TimeV[c],' ',69,yULine);
  492.                     for (i = 0; i < 14; ++i)
  493.                     {
  494.                         if (zChan[c].ad[i] != ' ')
  495.                         {
  496.                             ErasWriteB(zChan[c].ad[i],' ',ADX+30*i,yULine);
  497.                             ErasWriteB(zChan[c].ct[i]+'0',' ',CTX+30*i,yULine);
  498.                         }
  499.                     }
  500.                     Note[c] = ' ';
  501.                     Octave[c] = 0;
  502.                     TimeV[c] = ' ';
  503.                     for (i = 0; i < 14; ++i)
  504.                     {
  505.                         zChan[c].ad[i] = ' ';
  506.                         zChan[c].ct[i] = 0;
  507.                     }
  508.                     iAD = 0;
  509.                     kAD[c] = 0;
  510.                     ActiveCh();        /* Select non-blank chan to be active */
  511.                 }
  512.                 else if (address == ¬e_gadget)    /* Note gadget */
  513.                 {
  514.                     PrevChar = Note[c];
  515.                     Note[c] += 1;
  516.                     if (Note[c] > 'G') Note[c] = 'A';
  517.                     if (Note[c] < 'A') Note[c] = 'C';
  518.                     ErasWriteB(PrevChar,Note[c],0,yULine);
  519.                 }
  520.                 else if (address == &oct_gadget)    /* Octave gadget */
  521.                 {
  522.                     PrevChar = Octave[c] + '0';
  523.                     Octave[c] += 1;
  524.                     if (Octave[c] < 1) Octave[c] = 1;
  525.                     if (Octave[c] > 6) Octave[c] = 1;
  526.                     ErasWriteB(PrevChar,Octave[c]+'0',25,yULine);
  527.                 }
  528.                 else if (address == &time_gadget)    /* TimeV gadget */
  529.                 {
  530.                     PrevChar = TimeV[c];
  531.                     TimeV[c] += 1;            /* OK val's are 1, 2, 4 */
  532.                     if (TimeV[c] == '3') TimeV[c] = '4';
  533.                     if (TimeV[c] > '4') TimeV[c] = '1';
  534.                     if (TimeV[c] < '1') TimeV[c] = '1';
  535.                     ErasWriteB(PrevChar,TimeV[c],69,yULine);
  536.                 }
  537.                 else if (address == &lad_gadget)        /* < gadget */
  538.                 {
  539.                     iAD -= 1;
  540.                     if (iAD < 0 || iAD > 13) iAD = 0;
  541.                     ULine(30*iAD,yULine);
  542.                 }
  543.                 else if (address == &rad_gadget)        /* > gadget */
  544.                 {
  545.                     iAD += 1;
  546.                     if (iAD > 13) iAD = 13;
  547.                     if (iAD < 0) iAD = 0;
  548.                     ULine(30*iAD,yULine);
  549.                     if (zChan[c].ad[iAD] == ' ')
  550.                     {
  551.                         zChan[c].ad[iAD] = 'A';
  552.                         ErasWriteB(' ','A',ADX+30*iAD,yULine);
  553.                         zChan[c].ct[iAD] = 1;
  554.                         ErasWriteB(' ',1+'0',CTX+30*iAD,yULine);
  555.                         kAD[c] += 1;
  556.                     }
  557.                 }
  558.                 else if (address == &adr_gadget)        /* ADR+ gadget */
  559.                 {
  560.                     PrevChar = zChan[c].ad[iAD];
  561.                     if (zChan[c].ad[iAD] == 'A') zChan[c].ad[iAD] = 'D';
  562.                     else if (zChan[c].ad[iAD] == 'D') zChan[c].ad[iAD] = 'R';
  563.                     else if (zChan[c].ad[iAD] == 'R')
  564.                     {
  565.                         zChan[c].ad[iAD] = '+';
  566.                         a = zChan[c].ct[iAD] + '0';
  567.                         zChan[c].ct[iAD] = 0;        /* Set count = 0 & write blank*/
  568.                         ErasWriteB(a,' ',CTX+30*iAD,yULine);
  569.                     }
  570.                     else 
  571.                     {    zChan[c].ad[iAD] = 'A';
  572.                         zChan[c].ct[iAD] = 1;        /* Set count = 1 and write */
  573.                         ErasWriteB(' ',1+'0',CTX+30*iAD,yULine);
  574.                     }
  575.                     ErasWriteB(PrevChar,zChan[c].ad[iAD],ADX+30*iAD,yULine);
  576.                 }
  577.                 else if (address == &cad_gadget && zChan[c].ad[iAD] != '+')
  578.                 {
  579.                     PrevChar = zChan[c].ct[iAD] + '0';
  580.                     zChan[c].ct[iAD] += 1;
  581.                     if (zChan[c].ct[iAD] > 4) zChan[c].ct[iAD] = 1;
  582.                     if (zChan[c].ct[iAD] < 1) zChan[c].ct[iAD] = 1;
  583.                     ErasWriteB(PrevChar,zChan[c].ct[iAD]+'0',CTX+30*iAD,yULine);
  584.                 }
  585.                 else if (address == &ins_gadget)    /* Insert AD entry gadget */
  586.                 {
  587.                     if (kAD[c] < 14)        /* Insert OK if line is not full */
  588.                     {                        /* Insert at position iAD of ADR+ line */
  589.                         for (i = kAD[c]-1; i > iAD-1; --i)
  590.                         {
  591.                         /* For each AD entry including the insert and following, */
  592.                             /* move the entry one position to right (higher). */
  593.                     ErasWriteB(zChan[c].ad[i+1],zChan[c].ad[i],ADX+30*(i+1),yULine);
  594.                     if (zChan[c].ad[i] != '+')
  595.                     ErasWriteB(zChan[c].ct[i+1]+'0',zChan[c].ct[i]+'0',CTX+30*(i+1),yULine);
  596.                     else    /* No count for '+', just erase old count */
  597.                     ErasWriteB(zChan[c].ct[i+1]+'0',' ',CTX+30*(i+1),yULine);
  598.                             zChan[c].ad[i+1] = zChan[c].ad[i];
  599.                             zChan[c].ct[i+1] = zChan[c].ct[i];
  600.                         }
  601.                                 /* Erase the insert position and initialize */
  602.                         ErasWriteB(zChan[c].ad[iAD],'A',ADX+30*iAD,yULine);
  603.                         ErasWriteB(zChan[c].ct[iAD]+'0','1',CTX+30*iAD,yULine);
  604.                         zChan[c].ad[iAD] = 'A';
  605.                         zChan[c].ct[iAD] = 1;
  606.                         kAD[c] += 1;        /* Increm count for this line */
  607.                     }
  608.                 }
  609.                 else if (address == &dad_gadget)    /* Delete AD entry */
  610.                 {
  611.                     if (iAD > 0 || kAD[c] > 1)
  612.                     {
  613.                         for (i = iAD; i < kAD[c]-1; ++i)
  614.                         {
  615.                             /* For each AD entry following the delete, */
  616.                             /* move the entry one position to left (lower). */
  617.                     ErasWriteB(zChan[c].ad[i],zChan[c].ad[i+1],ADX+30*i,yULine);
  618.                     if (zChan[c].ad[i+1] != '+')
  619.                     ErasWriteB(zChan[c].ct[i]+'0',zChan[c].ct[i+1]+'0',CTX+30*i,yULine);
  620.                     else    /* No count for '+', just erase old count */
  621.                     ErasWriteB(zChan[c].ct[i]+'0',' ',CTX+30*i,yULine);
  622.                             zChan[c].ad[i] = zChan[c].ad[i+1];
  623.                             zChan[c].ct[i] = zChan[c].ct[i+1];
  624.                         }
  625.                                 /* Erase the last AD entry */
  626.                         i = kAD[c] - 1;
  627.                         ErasWriteB(zChan[c].ad[i],' ',ADX+30*i,yULine);
  628.                         ErasWriteB(zChan[c].ct[i]+'0',' ',CTX+30*i,yULine);
  629.                         zChan[c].ad[i] = ' ';
  630.                         zChan[c].ct[i] = 0;
  631.                         if (iAD == i) {iAD -= 1; ULine(30*iAD,yULine);}
  632.                         kAD[c] -= 1;
  633.                     }
  634.                 }
  635.                 else if (address == &tempo_gadget)        /* Tempo gadget */
  636.                 {
  637.                     tp_text.FrontPen = 0;
  638.                     PrintIText (w->RPort,&tp_text,0,0);
  639.                     Tempo = 500 - (float)tempo_info.HorizPot/MAXPOT * 400;
  640.                     /* Tempo:  value xyz in range 500--100 (= .5 sec--.1 sec) */
  641.                     val = (Tempo + 5)/ 10;    /* Save xy rounded */
  642.                     for (i = 2; i > 0; --i)    /* Convert to char -- .xy */
  643.                     {
  644.                         ttext[i] = val%10 + '0';
  645.                         val = val/10;
  646.                     }
  647.                     tp_text.FrontPen = 1;
  648.                     PrintIText (w->RPort,&tp_text,0,0);
  649.                 }
  650.         }    /* close switch(class) */
  651.     }        /* close while(msg...) */
  652.  }            /* close while(!fin) */
  653.  
  654.  ClearMenuStrip(w);
  655.  CloseWindow(w);
  656.  CloseLibrary(IntuitionBase);
  657. }
  658.  
  659.  
  660.  
  661. InitWindow()        /* Check for NTSC (American) or PAL (European), */
  662.                         /* Initialize window display:  draw grid, enter text, */
  663.                         /* initialize menu */
  664. {
  665.     int i;
  666.  
  667. GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
  668. if (!GfxBase)
  669. {
  670.     stext_request.IText = 
  671.     "Can't open Graphics Library for NTSC/PAL test -- assume NTSC";
  672.     AutoRequest(w,&stext_request,NULL,&sok_request,NULL,NULL,640,72);
  673.     goto SetNTSC;
  674. }
  675.  
  676. if (GfxBase->DisplayFlags & NTSC)
  677. {
  678. SetNTSC:
  679.     TicksPerSec = 3579545;    /* NTSC -- American */
  680. }
  681. else TicksPerSec = 3546895;    /* PAL -- European */
  682.  
  683. if (GfxBase) CloseLibrary(GfxBase);
  684.  
  685. SetMenuStrip(w,&smenu);
  686.  
  687. DrawBorder(w->RPort,&g_border,0,0);        /* Draw grid */
  688. strcpy(ptext,"Clear");
  689. PrintIText(w->RPort,&int_text,-106,-14);    /* Put text on screen */
  690. strcpy(ptext,"Chan");
  691. PrintIText(w->RPort,&int_text,-56,-14);
  692. ptext[1] = '\0';
  693. for (i = 0; i < 4; ++i)
  694. {    ptext[0] = i + '0';
  695.     PrintIText(w->RPort,&int_text,-34,i*CIN);
  696. }
  697. ptext[0] = 'N';
  698. PrintIText(w->RPort,&int_text,0,-14);
  699. ptext[0] = 'O';
  700. PrintIText(w->RPort,&int_text,25,-14);
  701. ptext[0] = 'T';
  702. PrintIText(w->RPort,&int_text,60,-14);
  703. strcpy(ptext,"ADR+");
  704. PrintIText(w->RPort,&int_text,ADX,-14);
  705. ptext[1] = '\0';
  706.  
  707.  ErasWriteB(' ',Note[0],0,0);            /* Put chan 0 startup val's on screen*/
  708.  ErasWriteB(' ',Octave[0]+'0',25,0);
  709.  ErasWriteB(' ',TimeV[0],69,0);
  710.  ErasWriteB(' ',zChan[0].ad[0],ADX,0);
  711.  ErasWriteB(' ',zChan[0].ct[0]+'0',CTX,0);
  712.  ktext[0] = Key;
  713.  PrintIText(w->RPort,&ky_text,0,0);
  714.  ktext[0] = Key2;
  715.  PrintIText(w->RPort,&ky_text,30,0);
  716.  ktext[0] = cyc;
  717.  PrintIText(w->RPort,&ky_text,CYXI,0);
  718.  PrintIText(w->RPort,&tp_text,0,0);
  719.  for (i = 0; i < 5; ++i)
  720.  {                                    /* Add Tempo gadget calibration markers */
  721.     DrawBorder(w->RPort,&calborder,i*46+6,0);
  722.     ctex[1] = 5 - i + '0';
  723.     PrintIText(w->RPort,&cal_text,i*46+6,0);
  724.  }
  725.  PrintIText(w->RPort,&tv_text,0,0);
  726.  ULine(0,0); iAD = 0;
  727.  
  728. }        /* Close function InitWindow */
  729.  
  730.  
  731.  
  732. InitChan()        /* Initialize chan 'c' values & display */
  733. {
  734. int i;
  735.  
  736. if (Note[0] != ' ') Note[c] = Note[0];
  737. else Note[c] = 'C';
  738. Octave[c] = 1;
  739. TimeV[c] = '1';
  740. zChan[c].ad[0] = 'A';
  741. zChan[c].ct[0] = 1;
  742. ErasWriteB(' ',Note[c],0,CIN*c);
  743. ErasWriteB(' ',Octave[c]+'0',25,CIN*c);
  744. PrintIText(w->RPort,&tv_text,0,CIN*c);
  745. ErasWriteB(' ',TimeV[c],69,CIN*c);
  746. ULine(0,CIN*c);
  747. ErasWriteB(' ','A',ADX,CIN*c);
  748. ErasWriteB(' ','1',CTX,CIN*c);
  749. kAD[c] = 1;
  750. }
  751.  
  752. ErasWriteA(pchar,nchar,x,y)    /* Erase a char, write a new char */
  753.   char pchar,nchar;
  754.   int x,y;
  755. {
  756. ktext[0] = pchar;
  757. ky_text.FrontPen = 0;
  758. PrintIText(w->RPort,&ky_text,x,y);
  759. ktext[0] = nchar;
  760. ky_text.FrontPen = 1;
  761. PrintIText(w->RPort,&ky_text,x,y);
  762. }
  763.  
  764. ErasWriteB(pchar,nchar,x,y)    /* Erase a char, write a new char */
  765.   char pchar,nchar;
  766.   int x,y;
  767. {
  768. ptext[0] = pchar;
  769. int_text.FrontPen = 0;
  770. PrintIText(w->RPort,&int_text,x,y);
  771. ptext[0] = nchar;
  772. int_text.FrontPen = 1;
  773. PrintIText(w->RPort,&int_text,x,y);
  774. }
  775.  
  776.  
  777.         /* Function ULine -- Underline (^^) for ADR+ display */
  778.         /* Also draws the orange box enclosing the selected chan, if needed */
  779.  
  780. SHORT sbox[] = {0,0,  617,0,  617,16,  0,16,  0,0};
  781. struct Border sborder = {GG+ZX+4,29,3,0,JAM1,5,sbox,NULL};
  782.  
  783. ULine(x,y)        /* Display underline (^^):  erase old, write new */
  784.   int x,y;        /* If x < 0, just erase, do not write new one. */
  785.                     /* If a new chan is selected, erase the old orange box,*/
  786.                     /* draw the new orange box. */
  787. {
  788. static int sx=-1, sy=-1;
  789.  
  790.  if (sx > -1)
  791.  {                /* Erase previous underline */
  792.     uln_text.FrontPen = 0;
  793.     PrintIText(w->RPort,&uln_text,sx,sy);
  794.     if (y != sy)
  795.     {            /* Erase previous select box */
  796.         sborder.FrontPen = 0;
  797.         DrawBorder(w->RPort,&sborder,0,sy);
  798.     }
  799.  }
  800.  if (x > -1)
  801.  {                /* Write new underline */
  802.     uln_text.FrontPen = 1;
  803.     PrintIText(w->RPort,&uln_text,x,y);
  804.     if (y != sy)
  805.     {            /* Draw new select box */
  806.         sborder.FrontPen = 3;
  807.         DrawBorder(w->RPort,&sborder,0,y);
  808.     }
  809.  }
  810.  sx = x; sy = y;
  811. }
  812.  
  813.  
  814.  
  815. WriteScale(file)        /* Write scale specs to output */
  816.     UBYTE file[];
  817. {
  818.  int i,j,k,m;
  819.  char cbuf[136],tempoC[3];
  820.  FILE *out;
  821.  
  822.  out = fopen (file,"w");
  823.  if (out == NULL)
  824.  {
  825.     stext_request.IText = "Can't open output file.";
  826.     AutoRequest (w,&stext_request,NULL,&sok_request,NULL,NULL,320,72);
  827.     return;
  828.  }
  829.  
  830.  cbuf[0] = Key;
  831.  cbuf[1] = Key2;
  832.  cbuf[2] = cyc;
  833.  itoa (Tempo,tempoC);
  834.  cbuf[3] = tempoC[0];
  835.  cbuf[4] = tempoC[1];
  836.  cbuf[5] = tempoC[2];
  837.  cbuf[6] = '\n';
  838.  
  839.  for (i = 0; i < 4; ++i)
  840.  {
  841.     k = 32*i + 7;
  842.     cbuf[k] = Note[i];
  843.     cbuf[k+1] = Octave[i] + '0';
  844.     cbuf[k+2] = TimeV[i];
  845.  
  846.     for (j = 0; j < 14; ++j)
  847.     {
  848.         m = k + 3 + 2*j;
  849.         cbuf[m] = zChan[i].ad[j];
  850.         cbuf[m+1] = zChan[i].ct[j] + '0';
  851.     }
  852.     cbuf[k+31] = '\n';
  853.  }
  854.  cbuf[135] = '\0';
  855.  
  856.  fputs(cbuf,out);
  857.  fclose(out);
  858. }        /* Close WriteScale */
  859.  
  860. itoa(integ,ascii)        /* Integer to Ascii */
  861.   int integ;            /* 3-digit integer */
  862.   char ascii[];
  863. {
  864.  int i, n;
  865.  
  866.  n = integ;
  867.  for (i = 2; i > -1; --i)
  868.  {
  869.     if (n > 0) 
  870.     {    ascii[i] = (n % 10) + '0';
  871.         n = n / 10;
  872.     }
  873.     else ascii[i] = ' ';
  874.  }
  875. }
  876.  
  877. ReadScale(file)        /* Read saved scale, reconstruct & display components */
  878.     UBYTE file[];
  879. {
  880.  int i,j,k,val;
  881.  char cbuf[35];
  882.  FILE *in;
  883.  
  884.  in = fopen(file,"r");
  885.  if (in == NULL)
  886.  {
  887.     stext_request.IText = "Can't find/open input file.";
  888.     AutoRequest (w,&stext_request,NULL,&sok_request,NULL,NULL,320,72);
  889.     return;
  890.  }
  891.  
  892.  fgets((char *)cbuf,8,in);
  893.  
  894.  PrevChar = Key;                /* Key */
  895.  Key = cbuf[0];
  896.  ErasWriteA(PrevChar,Key,0,0);
  897.  
  898.  PrevChar = Key2;                /* Key2 (# or b) */
  899.  Key2 = cbuf[1];
  900.  ErasWriteA(PrevChar,Key2,30,0);
  901.  
  902.  PrevChar = cyc;                /* cycle */
  903.  cyc = cbuf[2];
  904.  if (cyc == 'Y') cycle = TRUE; else cycle = FALSE;
  905.  ErasWriteA(PrevChar,cyc,CYXI,0);
  906.  
  907.  tp_text.FrontPen = 0;                /* Tempo */
  908.  PrintIText(w->RPort,&tp_text,0,0);
  909.  cbuf[0] = cbuf[3]; cbuf[1] = cbuf[4]; cbuf[2] = cbuf[5]; cbuf[3] = '\0';
  910.  Tempo = atoi(cbuf);
  911.  val = (Tempo+5)/10;        /* Round to 2 digits */
  912.  ttext[2] = val%10 + '0';
  913.  ttext[1] = val/10 + '0';
  914.  ttext[0] = '.';
  915.  ttext[3] = '\0';
  916.  tp_text.FrontPen = 1;
  917.  PrintIText(w->RPort,&tp_text,0,0);
  918.         /* Reposition slider knob for current value of Tempo */
  919.  ModifyProp(&tempo_gadget,w,NULL, FREEHORIZ | AUTOKNOB,
  920.                 MAXPOT * (500 - Tempo) / 400,        /* Slider position */
  921.                 0,MAXBODY * 1/400,0);
  922.  
  923.  for (i = 0; i < 4; ++i)
  924.  {
  925.     k = i*CIN;
  926.     fgets((char *)cbuf,33,in);        /* Read in a channel */
  927.  
  928.     PrevChar = Note[i];
  929.     Note[i] = cbuf[0];
  930.     ErasWriteB(PrevChar,Note[i],0,k);
  931.  
  932.     PrevChar = Octave[i] + '0';
  933.     Octave[i] = cbuf[1] - '0';
  934.     if (cbuf[1] == '0') cbuf[1] = ' ';
  935.     ErasWriteB(PrevChar,cbuf[1],25,k);
  936.  
  937.     PrevChar = TimeV[i];
  938.     TimeV[i] = cbuf[2];
  939.     ErasWriteB(PrevChar,TimeV[i],69,k);
  940.     if (TimeV[i] == ' ') tv_text.FrontPen = 0;
  941.     else tv_text.FrontPen = 1;
  942.     PrintIText(w->RPort,&tv_text,0,k);    /* This does the "1/" for Time */
  943.     tv_text.FrontPen = 1;
  944.  
  945.     kAD[i] = 0;
  946.     for (j = 0; j < 14; ++j)
  947.     {
  948.         PrevChar = zChan[i].ad[j];
  949.         zChan[i].ad[j] = cbuf[2*j+3];
  950.         ErasWriteB(PrevChar,zChan[i].ad[j],ADX+30*j,k);
  951.         if (zChan[i].ad[j] != ' ') kAD[i] += 1;
  952.  
  953.         PrevChar = zChan[i].ct[j] + '0';
  954.         zChan[i].ct[j] = cbuf[2*j+4] - '0';
  955.         if (cbuf[2*j+4] == '0') cbuf[2*j+4] = ' ';
  956.         ErasWriteB(PrevChar,cbuf[2*j+4],CTX+30*j,k);
  957.     }
  958.  }        /* Close for(i=... */
  959.  ActiveCh();        /* Find first non-blank chan for active */
  960. }        /* Close ReadScale() */
  961.  
  962.  
  963.  
  964. UseFileWindow()    /* Invoke function FileWindow to find the file name */
  965. {                        /* for reads and writes. */
  966.  UBYTE file[TOTAL_LENGTH];
  967.  USHORT operation;
  968.  
  969.  operation = FileWindow(file);
  970.  
  971.  switch (operation)
  972.  {
  973.     case LOAD:
  974.         ReadScale(file);
  975.         break;
  976.     case SAVE:
  977.         WriteScale(file);
  978.         break;
  979.     case CANCEL:
  980.     case QUIT:
  981.     case PANIC1:
  982.         break;
  983.     case PANIC2:
  984.         printf ("System error--can't open window for FileWindow\n");
  985.         break;
  986.     default:
  987.         printf ("FileWindow serious problem, cause unknown.  GET HELP!\n");
  988.  }
  989. }
  990.  
  991. ActiveCh()        /* Find the 1st non-blank chan, make it active */
  992. {
  993.  int i;
  994.  for (i = 0; i < 4; ++i)
  995.  {
  996.     if (Note[i] != ' ')
  997.     {
  998.         iAD = 0;
  999.         c = i;
  1000.         yULine = i*CIN;
  1001.         ULine(0,yULine);
  1002.         return;
  1003.     }
  1004.  }
  1005.     /* No active channel--erase old marker, no new one */
  1006.  ULine(-1,0);
  1007. }
  1008.