#include"\c\colors.h"

#include<stdarg.h>
#include<stdio.h>
#include<stdlib.h>
#include<dos.h>

#define TRUE 1
#define FASLE 0

/* PC800 : roland jx-8p programmer/sound librarian */

/*----- global variables -------------------------------------------*/

     char cr1[50]="(C)opyright 1987 BP MIDI Systems";
     char cr2[50]="Written by Mike Partain";
     char cr3[50]="6071 Heatherwood drive";
     char cr4[50]="Alexandria, Virginia 22310";
     char cr5[50]="portions copyright 1986 Borland";

     int midi_x_data[5][65];
     int patch=0;

     int done,current_parm,cur_curs;

  char parm_name[59][13]={
"","","","","","","","","","",
"",
"range","waveform","tune","lfo","env",
"range","waveform","crossmod","tune","fine_tune","lfo","env",
"","","",
"dynamics","ENV mode",
"dco-1","dco-2","env","dynamics","mode",
"hpf","cutoff","res","lfo","env","key_follow","dynamics","mode",
"level","dynamics",
"mode",
"waveform","delay_time","rate",
"attack","decay","sustain","release","key_follow",
"attack","decay","sustain","release","key_follow",
"",
"Env mode"};

 int parm_x[59]={         /* this defines where data will go  */
                          /* the title will be 15 behind it  */
                          /* a value of 0 indicates no data ! */
16,0,0,0,0,0,0,0,0,0,
0,
16,31,46,61,76,
16,31,46,61,76,16,31,
0,0,0,
16,31,
16,31,46,61,76,
16,31,46,61,76,16,31,46,
16,31,
16,
16,31,46,
16,31,46,61,76,
16,31,46,61,76,
0,
46};
 int parm_y[59]={   /* this defines where data will go  */
                          /* the title will be 15 behind it  */
                          /* a value of 0 indicates no data ! */
4,0,0,0,0,0,0,0,0,0,
0,
6,6,6,6,6,
7,7,7,7,7,8,8,
0,0,0,
10,10,
11,11,11,11,11,
12,12,12,12,12,13,13,13,
15,15,
16,
18,18,18,
20,20,20,20,20,
21,21,21,21,21,
0,
15};

int parm_color[59]={
white,white,white,white,white,white,white,white,white,white,
0,
red,red,red,red,red,
blue,blue,blue,blue,blue,blue,blue,
0,0,0,
green,green,
brown,brown,brown,brown,brown,
magenta,magenta,magenta,magenta,magenta,magenta,magenta,magenta,
cyan,cyan,
white,
brown,brown,brown,
blue,blue,blue,blue,blue,
magenta,magenta,magenta,magenta,magenta,
0,
cyan};

char tittle[11][10]={"NAME","DCO-1","DCO-2","DCO","MIXER",
                      "VCF","VCA","CHORUS","LFO","ENV-1","ENV-2"};
int tittle_y[11]={4,6,7,10,11,12,15,16,18,20,21};
int tittle_color[11]={white,red,blue,green,brown,magenta,cyan,white,
brown,blue,magenta};

/*------------------------------------------------------------------*/
midi_exclusive()
 { int a,i,type;
   a=rc_dta_wt();
   type=rc_dta_wt();
   for (i=1;i<=4;++i) a=rc_dta_wt();   /* junk <--- fix !! ---< */
   if (type==0x35) {     /* APR */
                    for (i=0;i<=58;++i) midi_x_data[patch][i]=rc_dta_wt();
                    a=rc_dta_wt();
                    if (a!=0xf7) xabort(5);
                    else show_midi_x_data();
                   }
   else {               /* IPR */
         if (type!=0x36) warning("type!=x35 or x36");
         else  do {
                   a=rc_dta_wt();
                   if (a!=0xf7) {
                       midi_x_data[patch][a]=rc_dta_wt();
                       save_cursor();
                       show_parm(a);
                       restore_cursor();
                                }
                  } while (a!=0xf7);
        }
 }
/*------------------------------------------------------------------*/
show_parm(a)
int a;
{
 if (a<=9) show_name();
 else {
       if (parm_x[a]!=0) {
           switch(a)
        {  case (12):
           case (17): special(a,"noi ","squ ","pul ","saw "); break;
           case (11):
           case (16): special(a,"16' "," 8' "," 4' "," 2' "); break;
           case (27):
           case (32):
           case (40): env_mode(a); break;
           case (26):
           case (31):
           case (39):
           case (42):
           case (51):
           case (56): special(a,"off ","  1 ","  2 ","  3 ");break;
           case (18): special(a,"off ","syn1","syn2","xmod");break;
           case (58): special(a,"gate","gate","env2","env2");break;
           case (44): special(a,"rnd ","sqr ","tri ","tri ");break;
           case (43): special(a,"off ","  1 ","  2 ","  2 ");break;
           case (33): special(a,"  0 ","  1 ","  2 ","  3 ");break;


           default: { gotoxy(parm_x[a],parm_y[a]);
                      color(parm_color[a]+bold);
                      printf("%3d ",midi_x_data[patch][a]);
                    }
        }
                         }
      }
}
/*------------------------------------------------------------------*/
special(a,p1,p2,p3,p4) int a; char *p1,*p2,*p3,*p4;
{
 gotoxy(parm_x[a],parm_y[a]);
 color(parm_color[a]+bold);
 if      (midi_x_data[patch][a]<=31)  printf("%4s",p1);
 else if (midi_x_data[patch][a]<=63)  printf("%4s",p2);
 else if (midi_x_data[patch][a]<=95)  printf("%4s",p3);
 else if (midi_x_data[patch][a]<=127) printf("%4s",p4);
}
/*------------------------------------------------------------------*/
env_mode(a)
int a;
{
 gotoxy(parm_x[a],parm_y[a]);
 color(parm_color[a]+bold);
 if (midi_x_data[patch][a]<=31) printf(" 2%c",25);
 else if (midi_x_data[patch][a]<=63) printf(" 2%c",24);
 else if (midi_x_data[patch][a]<=95) printf(" 1%c",25);
 else if (midi_x_data[patch][a]<=127) printf(" 1%c",24);
}
/*------------------------------------------------------------------*/
draw_screen()
{int i,x;
 for (i=0;i<=10;++i) {
        gotoxy(1,tittle_y[i]);
        color(tittle_color[i]+bold);
        printf("%s",tittle[i]);
                     }
 for (i=0;i<=58;++i) {
        if (parm_x[i]!=0) {
            x=parm_x[i]-strlen(parm_name[i])-1;
            gotoxy(x,parm_y[i]);
            color(parm_color[i]+bold);
            printf("%s",parm_name[i]);
                           }
                     }
 gotoxy(5,24); color(white+bold);
 printf("F1 Save / F2 Load / F3 Dir / F4 Send / F5 Shell /");
 printf("F6 Name / F10 Exit");
 locate(25,26); color(white+bold);
 printf("F7 Patch Up / F8 Patch Down");
 locate(2,1);
 color(green+bold);
 printf("Current patch %d",patch+1);
 color(normal);
}

/*------------------------------------------------------------------*/
show_midi_x_data()
{ int i;
  save_cursor();
  locate(2,1);
  color(green+bold);
  printf("Current patch %d",patch+1);
  for (i=11;i<=58;++i) show_parm(i);
  show_name();
  restore_cursor();
  mov_curs();
}
/*------------------------------------------------------------------*/
show_name()
{
  int i;
  save_cursor();
  gotoxy(10,4); color(white+bold);
  for (i=0;i<=9;i++)
   if (midi_x_data[patch][i]!=0) printf("%c",midi_x_data[patch][i]); /* name */
  restore_cursor();
}
/*------------------------------------------------------------------*/
pffunc1()
{
}
/*------------------------------------------------------------------*/
func_key()
{
 char c;
 c=getch();
 switch (c) {
  case (0x3b): save_patch(); break;
  case (0x3c): load_patch(); break;
  case (0x3d): patch_dir(); break;
  case (0x3e): send_apr(); break;
  case (0x3f): shell(); break;
  case (0x40): new_name(); break;
  case (0x41): patch_down(); break;
  case (0x42): patch_up(); break;
  case (0x43): pffunc1(); break;
  case (0x44): quit(); break;
  case (0x4d): parm_right(); break;
  case (0x4b): parm_left(); break;
  case (0x48): parm_up(); break;
  case (0x50): parm_down(); break;
  case (0x49): change_down(current_parm,5); break;
  case (0x51): change_up(current_parm,5); break;
  case (0x68): save_set(); break;
  case (0x69): load_set(); break;
  case (0x6a): set_dir(); break;
            }

}
/*------------------------------------------------------------------*/
quit()
{
 char yn;
 screen(1); cls();
 printf("Are you sure you want to exit (Y/N)?");
 yn=getch();
 if (toupper(yn)=='Y') done=TRUE;
 screen(0);
}
/*------------------------------------------------------------------*/
patch_up()
{
 patch++;
 if (patch>4) patch=0;
 show_midi_x_data();
}
patch_down()
{
 patch--;
 if (patch<0) patch=4;
 show_midi_x_data();
}
/*------------------------------------------------------------------*/
new_name()
{
 int i;
 char name[11];
 screen(1); cls();
 for (i=0;i<=10;i++) name[i]=midi_x_data[patch][i];
 name[10]='\0';
 color(green+bold);
 printf("Current name:%s\n",name);
 color(yellow);
 printf("Enter new name for patch?");
 scanf("%s",name);
 i=0;
 while ((i<=10) & (name[i]!='\0'))
  {
   midi_x_data[patch][i]=toupper(name[i]);
   ++i;                                          /* copy to brk */
  }
/* pad w/blanks */
 if (i!=10) for (i=i;i<=10;i++) midi_x_data[patch][i]=' ';

 screen(0);
 show_name();
}
/*------------------------------------------------------------------*/
load_patch()
{
 int i;
 int ok=FASLE;
 FILE *fp, *fopen();
 char *fn[20];
 char *fe;

      screen(1); cls();
      color(red+bold);
      printf("\nLOAD");
      color(blue);
      printf(" - enter file name:");
      scanf("%s",fn);
      printf("\n");

      fe=".jx8";
      strncat(fn,fe,20);

      if ((fp = fopen(fn, "r"))==NULL) {
             color(red);
             printf("bad open\n");
                                    }
      else     {
                i=0;
                while ((midi_x_data[patch][i++]=getc(fp))!=EOF);
                fclose(fp);
/* design note 'i' = 60 because EOF was counted !!! */
                if (i!=60) {color(red); printf("bad data\n");}
                else {color(green); printf("load ok\n");ok=TRUE;}
               }
 wait_key();
 screen(0);
 if (ok) show_midi_x_data();
}
/*------------------------------------------------------------------*/
save_patch()
{
 int a;
 FILE *fp, *fopen();
 char *fn[20];
 char *fe;

      screen(1); cls();
      color(red+bold);
      printf("\nWrite");
      color(blue);
      printf(" - enter file name:");
      scanf("%s",fn);
      printf("\n");

      fe=".jx8";
      strncat(fn,fe,20);

      if ((fp = fopen(fn, "w"))==NULL) {
                color(red+bold);
                printf("bad open\n");
                                    }
      else     {
                for (a=0;a<=58;a++) putc(midi_x_data[patch][a],fp);
                fclose(fp);
                color(green+bold);
                printf("write ok\n");
               }
 wait_key();
 screen(0);
}
/*------------------------------------------------------------------*/
send_ipr(parm) int parm;
{
 sn_cmd(0xdf);   /* want to send message */
 sn_dta(0xf0); /* sys exclusive          */
 sn_dta(0x41); /* roland id              */
 sn_dta(0x36); /* IPR mode               */
 sn_dta(0x00); /* channel                */
 sn_dta(0x21); /* format type JX-8P      */
 sn_dta(0x20); /* level #                */
 sn_dta(0x01); /* group #                */
 sn_dta(parm); /* parm to chnge          */
 sn_dta(midi_x_data[patch][parm]); /* new value */
 sn_dta(0xf7); /* end of ex data         */
/* why couldn't mirage be that simple?!  */
}
/*------------------------------------------------------------------*/
send_apr()
{
 int i;
  sn_cmd(0xdf);   /* want to send message */
 sn_dta(0xf0); /* sys exclusive          */
 sn_dta(0x41); /* roland id              */
 sn_dta(0x35); /* APR mode               */
 sn_dta(0x00); /* channel                */
 sn_dta(0x21); /* format type JX-8P      */
 sn_dta(0x20); /* level #                */
 sn_dta(0x01); /* group #                */
 for (i=0;i<=58;i++) sn_dta(midi_x_data[patch][i]);
 sn_dta(0xf7); /* end of ex data         */
}
/*------------------------------------------------------------------*/
change_up(parm,amt) int amt,parm;
{
 if (midi_x_data[patch][parm]<127) {
     switch (parm)  {
       case(11):;   case(12):;
       case(16):;   case(17):;   case(18):;
       case(26):;   case(27):;   case(31):;
       case(32):;   case(33):;   case(39):;
       case(40):;   case(42):;   case(43):;
       case(44):;   case(56):;
       case(58):           /* they all fall to here */
                   if (midi_x_data[patch][parm]<96)
                       midi_x_data[patch][parm]+=32;
                   break;
       default:    midi_x_data[patch][parm]+=amt;
                   break;
                    }
     if (midi_x_data[patch][parm]>127) midi_x_data[patch][parm]=127;
     show_parm(parm);
     send_ipr(parm);
                            }
}
/*------------------------------------------------------------------*/
change_down(parm,amt) int amt,parm;
{
 if (midi_x_data[patch][parm]>0) {
     switch (parm)  {
       case(11):;   case(12):;
       case(16):;   case(17):;   case(18):;
       case(26):;   case(27):;   case(31):;
       case(32):;   case(33):;   case(39):;
       case(40):;   case(42):;   case(43):;
       case(44):;   case(56):;
       case(58):           /* they all fall to here */
                   if (midi_x_data[patch][parm]>31)
                       midi_x_data[patch][parm]-=32;
                   break;
       default:    midi_x_data[patch][parm]-=amt;
                   break;
                    }
     if (midi_x_data[patch][parm]<0) midi_x_data[patch][parm]=0;
     show_parm(parm);
     send_ipr(parm);
                            }
}
/*------------------------------------------------------------------*/
handle_kbd()
{
 char c;
 c=getch();
 switch (c) {
   case(0): func_key(); break;
   case(0x2d): change_down(current_parm,1); break;
   case(0x2b): change_up(current_parm,1); break;
            }
}
/*------------------------------------------------------------------*/
main()
{
 logo();
 open_midi();
 /* set_uart(); */
 sn_cmd(0x97); 	/* exclusive to host on */
/* for (i=0;i<=10000;i++) {for (j=0;j<=100;j++) {;} }  /* delay */ */
 cls();
 copy_right();
 draw_screen();
 done=FASLE;
 current_parm=11;
 cur_curs=0;
 mov_curs();

 while (!done) receive_midi_packet();

 cls();
 close_midi();
 color(normal);
 printf("\nNormal End.......\n");
 exit(0);
}
