#include #include #include #include "global.h" #include #include #include #include "mymsp.h" /*********************************************************************/ /* EXTERNALS */ /*********************************************************************/ extern int gl_apid; /*********************************************************************/ /* GLOBAL VARIABLES */ /*********************************************************************/ int gl_hchar; int gl_wchar; int gl_wbox; int gl_hbox; /* system sizes */ int menu_id ; /* our menu id */ int phys_handle; /* physical workstation handle */ int xdesk,ydesk,hdesk,wdesk; int hidden; /* current state of cursor */ int fulled; /* current state of window */ int contrl[12]; int intin[128]; int ptsin[128]; int intout[128]; int ptsout[128]; /* storage wasted for idiotic bindings */ int work_in[11]; /* Input to GSX parameter array */ int work_out[57]; /* Output from GSX parameter array */ int pxyarray[10]; /* input point array */ int pid; /* process ID number */ /* timer externals */ extern dispatcher(); /* labels in in-line assembly must be declared. */ extern set_timer(); extern unset_timer(); /* timer globals */ extern long ticks; /* local tick counter. */ long oldvector; /* storage for old terminate vector. */ EVENT_BUFFER time_out[16]; ASSIGNMENT track_info[16]; int current_preset[16]; int track_enables[4]; char *song_buffer,*song_data; long song_size; int active_song = FALSE; int default_loaded = FALSE; extern int active_timer; int time_sig,key_sig; int tempo; int event; /* event counter */ char temp[120],path[80],name[20]; /* file stuff */ char config_path[80],config_name[20]; /* config file stuff */ char song_name[34]; char *song_ram[24]; /* pointers to memory where songs are */ int song_msize[24]; char *song_list[24]; /* pointers to list of songs to play */ char song_names[1000]; /* names of the songs */ int song_pointer = 0; /* current song being acted on */ int number_of_songs = 0; /* total number of songs */ int song_index = 0; int jukebox = FALSE; /* are we in jukebox mode */ /* tables */ extern int key_sig_tab[128]; extern int s_octave[6][7]; extern ASSIGNMENT track_info[16]; extern int octave[6]; extern int end_flag; extern int done_flag; extern int done_handshake; char rev[] = "Revision 0.90"; /****************************************************************/ /* GSX UTILITY ROUTINES. */ /****************************************************************/ hide_mouse() { if(! hidden){ graf_mouse(M_OFF,0x0L); hidden=TRUE; } } show_mouse() { if(hidden){ graf_mouse(M_ON,0x0L); hidden=FALSE; } } /****************************************************************/ /* open virtual workstation */ /****************************************************************/ int open_vwork(handle) int handle; { int i; for(i=0;i<10;work_in[i++]=1); work_in[10]=2; v_opnvwk(work_in,&handle,work_out); return(handle); } /****************************************************************/ /* Accessory Init. Until First Event_Multi */ /****************************************************************/ main() { int drive; pid = appl_init(); phys_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox); menu_id=menu_register(gl_apid," MS Background"); wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk); mrsrc_load( MYMSPRSC); drive = Dgetdrv(); Dgetpath(path,drive+1); sprintf(temp,"%c:%s\\",drive + 'A',path); strcpy(path,temp); strcpy(config_path,temp); strcpy(config_name,"default.cfg"); init(); midi_init(); multi(); } /****************************************************************/ /* dispatches all accessory tasks */ /****************************************************************/ multi() { int event; int vw; int open_flag = FALSE; int msgbuff[8]; /* event message buffer */ int keycode; /* keycode returned by event-keyboard */ int mx,my; /* mouse x and y pos. */ int butdown = TRUE; /* button state tested for, UP/DOWN */ int ret; /* dummy return variable */ while (TRUE) { event = evnt_multi(MU_MESAG | MU_BUTTON | MU_KEYBD, 1,1,butdown, 0,0,0,0,0, 0,0,0,0,0, msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret); wind_update(TRUE); if (event & MU_MESAG) { switch (msgbuff[0]) { case AC_CLOSE: if((msgbuff[3] == menu_id)&&(open_flag == TRUE)) { v_clsvwk(vw); open_flag = FALSE; } break; case AC_OPEN: if (msgbuff[4] == menu_id) { if(open_flag == FALSE) { open_flag = TRUE; vw = open_vwork(phys_handle); if(!default_loaded) { load_config(config_path,config_name); default_loaded = TRUE; } do_menu(); v_clsvwk(vw); open_flag = FALSE; } } break; } /* switch (msgbuff[0]) */ wind_update(FALSE); } } /* while (TRUE) */ } int do_dialog(dialog,start) OBJECT *dialog; int start; { int cx,cy,cw,ch,result; if (dialog == (OBJECT *)(0)) { form_alert(1,"[1][Null pointer ERROR][OK]"); return(0); } else { form_center(dialog,&cx,&cy,&cw,&ch); form_dial(FMD_START,cx,cy,0,0,cx,cy,cw,ch); form_dial(FMD_GROW,cx,cy,0,0,cx,cy,cw,ch); objc_draw(dialog,0,10,cx,cy,cw,ch); result = form_do(dialog,start); form_dial(FMD_SHRINK,cx,cy,0,0,cx,cy,cw,ch); form_dial(FMD_FINISH,cx,cy,0,0,cx,cy,cw,ch); return(result); } } do_menu(vw) int vw; { int result; OBJECT *box; int x,y,w,h; int i; int dirty = TRUE; long mem_used; rsrc_gaddr(R_TREE,MAINMENU,&box); form_center(box,&x,&y,&w,&h); if(jukebox) box[MMLOAD].ob_state = DISABLED; if(!active_timer) box[MMSTOP].ob_state = DISABLED; form_dial(FMD_START,x,y,0,0,x,y,w,h); form_dial(FMD_GROW,x,y,0,0,x,y,w,h); do { if(dirty) { mem_used = 0l; for(i=0;i<24;++i) mem_used += (long)song_msize[i]; sprintf(temp,"%6ld",mem_used); strcpy(box[MMEMORY].ob_spec,temp); sprintf(temp,"%2d",number_of_songs); strcpy(box[NUMOFSNG].ob_spec,temp); objc_draw(box,0,10,x,y,w,h); dirty = FALSE; } result = form_do(box,0); switch(result) { case MMLOAD: if(!(box[result].ob_state & DISABLED)) { if(get_file_name(path,name,"*.SNG")) { strcpy(temp,path); strcat(temp,name); song_list[number_of_songs] = (char *)&song_names[song_index]; strcpy(song_list[number_of_songs],temp); song_index += strlen(song_list[number_of_songs]) +1; load_file(temp,number_of_songs); number_of_songs += 1; jukebox = TRUE; } objc_change(box,MMLOAD,0,x,y,w,h,NORMAL,1); objc_change(box,MLOADCON,0,x,y,w,h,DISABLED,1); objc_change(box,SONGLIST,0,x,y,w,h,DISABLED,1); objc_change(box,MMSTOP,0,x,y,w,h,NORMAL,1); dirty = TRUE; box[MDESTALL].ob_state = DISABLED; } break; case MMSTOP: if(!(box[result].ob_state & DISABLED)) { if(active_timer) { irq_dis(); if(done_handshake) done_handshake = FALSE; irq_en(); end_flag = TRUE; while(!done_handshake); /* wait until done */ done_handshake = FALSE; unset_timer(); } objc_change(box,MMSTOP,0,x,y,w,h,NORMAL,1); objc_change(box,MMSTOP,0,x,y,w,h, DISABLED,1); objc_change(box,MMSTART,0,x,y,w,h,NORMAL,1); } break; case MMABOUT: about(); dirty = TRUE; box[MMABOUT].ob_state = NORMAL; break; case SONGLIST: if(!(box[result].ob_state & DISABLED)) { get_song_list(); box[MDESTALL].ob_state = DISABLED; box[SONGLIST].ob_state = NORMAL; jukebox = TRUE; dirty = TRUE; } break; case MMSTART: if(!(box[result].ob_state & DISABLED)) { song_buffer = song_ram[song_pointer]; do_perform(vw); objc_change(box,MMSTART,0,x,y,w,h,NORMAL,1); objc_change(box,MMSTART,0,x,y,w,h, DISABLED,1); objc_change(box,MMSTOP,0,x,y,w,h,NORMAL,1); } break; case MSAVECON: save_config(); box[result].ob_state = NORMAL; dirty = TRUE; break; case MCLEAR: if(!(box[result].ob_state & DISABLED)) { if(active_timer) { irq_dis(); if(done_handshake) done_handshake = FALSE; irq_en(); end_flag = TRUE; /* stop everything first */ while(!done_handshake); /* wait until done */ done_handshake = FALSE; objc_change(box,MMSTOP,0,x,y,w,h,NORMAL,1); objc_change(box,MMSTOP,0,x,y,w,h, DISABLED,1); objc_change(box,MMSTART,0,x,y,w,h,NORMAL,1); unset_timer(); } for(i=0;i<24;++i) { if(song_ram[i] != NULL) { Mfree(song_ram[i]); song_ram[i] = NULL; song_list[i] = NULL; song_msize[i] = 0; } } song_pointer = 0; jukebox = FALSE; number_of_songs = 0; song_index = 0; active_song = FALSE; objc_change(box,MMLOAD,0,x,y,w,h,NORMAL,1); objc_change(box,MLOADCON,0,x,y,w,h,NORMAL,1); objc_change(box,SONGLIST,0,x,y,w,h,NORMAL,1); objc_change(box,MDESTALL,0,x,y,w,h,NORMAL,1); objc_change(box,MCLEAR,0,x,y,w,h,NORMAL,1); dirty = TRUE; } break; case MLOADCON: if(!(box[result].ob_state & DISABLED)) { if(get_file_name(config_path,config_name,"*.CFG")) { load_config(config_path,config_name); } dirty = TRUE; } objc_change(box,MLOADCON,0,x,y,w,h,NORMAL,1); box[MLOADCON].ob_state = DISABLED; box[MDESTALL].ob_state = DISABLED; break; case MINSTALL: if(!(box[result].ob_state & DISABLED)) { init_traps(); /* install MIDI trap vector */ init_vecs(); /* change key/midi irq vector */ objc_change(box,MINSTALL,0,x,y,w,h,NORMAL,1); objc_change(box,MINSTALL,0,x,y,w,h,DISABLED,1); objc_change(box,MMLOAD,0,x,y,w,h,NORMAL,1); objc_change(box,MLOADCON,0,x,y,w,h,NORMAL,1); objc_change(box,SONGLIST,0,x,y,w,h,NORMAL,1); objc_change(box,MMSTART,0,x,y,w,h,NORMAL,1); objc_change(box,MCLEAR,0,x,y,w,h,NORMAL,1); } break; case MDESTALL: if(!(box[result].ob_state & DISABLED)) { if(!active_timer) unset_timer(); /* disable the timer */ midi_cleanup(); /* restore TRAP 3 and interrupt vector */ objc_change(box,MINSTALL,0,x,y,w,h,NORMAL,1); objc_change(box,MDESTALL,0,x,y,w,h,NORMAL,1); objc_change(box,MDESTALL,0,x,y,w,h,DISABLED,1); objc_change(box,MMLOAD,0,x,y,w,h,DISABLED,1); objc_change(box,MLOADCON,0,x,y,w,h,DISABLED,1); objc_change(box,SONGLIST,0,x,y,w,h,DISABLED,1); objc_change(box,MMSTART,0,x,y,w,h,DISABLED,1); objc_change(box,MCLEAR,0,x,y,w,h,DISABLED,1); } break; case MMCAN: break; } /* end of switch result */ }while (result != MMCAN); box[result].ob_state = NORMAL; form_dial(FMD_SHRINK,x,y,0,0,x,y,w,h); form_dial(FMD_FINISH,x,y,0,0,x,y,w,h); } get_song_list() { OBJECT *box; int x,y,h,w; int save; char *ptr; register int i; int result; save = song_pointer; song_pointer = number_of_songs; rsrc_gaddr(R_TREE,SNGLIST,&box); form_center(box,&x,&y,&w,&h); form_dial(FMD_START,x,y,0,0,x,y,w,h); form_dial(FMD_GROW,x,y,0,0,x,y,w,h); do { objc_draw(box,0,10,x,y,w,h); result = form_do(box,0); switch(result) { case SLEXIT: break; case SLFIND: if(get_file_name(path,name,"*.SNG")) { ptr = (char *)(&song_names[song_index]); song_list[song_pointer] = ptr; for(i=0;path[i] != '\0';++i,++ptr) *ptr = path[i]; song_index += i; for(i=0;name[i] != '\0';++i,++ptr) *ptr = name[i]; *ptr = '\0'; load_file(song_list[song_pointer],song_pointer); ++song_pointer; song_index += i + 1; if(song_pointer > 23) { box[SLFIND].ob_state = NORMAL; box[SLFIND].ob_state |= DISABLED; } } break; } /* end of switch result */ box[result].ob_state = NORMAL; }while (result != SLEXIT); number_of_songs = song_pointer; song_pointer = save; form_dial(FMD_SHRINK,x,y,0,0,x,y,w,h); form_dial(FMD_FINISH,x,y,0,0,x,y,w,h); } gen_key_tab(key) int key; { register int i; for(i=0;i<128;++i) key_sig_tab[i] = 0; if( key == CMAJ ) return; /* nothing to do */ if(key <= CSMAJ) /* these all generate sharps */ { switch(key) { case CSMAJ: for(i=11;i<128;i += 12) key_sig_tab[i] = 1; case FSMAJ: for(i=4;i<128;i += 12) key_sig_tab[i] = 1; case BMAJ: for(i = 9;i<128;i += 12) key_sig_tab[i] = 1; case EMAJ: for(i = 2;i < 128;i += 12) key_sig_tab[i] = 1; case AMAJ: for(i = 7;i < 128;i += 12) key_sig_tab[i] = 1; case DMAJ: for(i=0;i < 128;i += 12) key_sig_tab[i] = 1; case GMAJ: for(i=5;i<128;i += 12) key_sig_tab[i] = 1; } } else /* these all generate flats */ { switch(key) { case CFMAJ: for(i=5;i < 128;i +=12) key_sig_tab[i] = -1; case GFMAJ: for(i=0;i < 128;i +=12) key_sig_tab[i] = -1; case DFMAJ: for(i=7;i < 128;i +=12) key_sig_tab[i] = -1; case AFMAJ: for(i=2;i < 128;i +=12) key_sig_tab[i] = -1; case EFMAJ: for(i=9;i < 128;i +=12) key_sig_tab[i] = -1; case BFMAJ: for(i=4;i < 128;i +=12) key_sig_tab[i] = -1; case FMAJ: for(i = 11;i < 128;i +=12) key_sig_tab[i] = -1; } } } load_file(n,i) char *n; int i; { int fd; /* file descriptor for input file */ DTA file_info; long old_dta; if(song_ram[i] != NULL) { Mfree(song_ram[i]); /* free up if used */ song_msize[i] = 0; } old_dta = (long)Fgetdta(); /* save the old DTA */ Fsetdta(&file_info); /* set address */ Fsfirst(n,0); /* get file info */ song_msize[i] = (int)file_info.fsize; song_ram[i] = (char *)Malloc(file_info.fsize); /* allocate memory for file */ fd = Fopen(n,0); /* open file for read */ song_size = Fread(fd,file_info.fsize,song_ram[i]); /* read data */ Fclose(fd); /* close file */ active_song = TRUE; Fsetdta(old_dta); } get_file_name(p,n,spec) char p[],n[],spec[]; { int but; int done; char *ptr; int status; done = FALSE; do { strcpy(temp,p); strcat(temp,spec); fsel_input(temp,n,&but); if(but == 1) /* ok */ { if((ptr = (char *)index(temp,'*')) != NULL) { *ptr = '\0'; strcpy(p,temp); } done = TRUE; status = TRUE; } else { status = FALSE; done = TRUE; } }while(!done); return(status); } init_buffer() { register int i; for(i=0;i<16;++i) { time_out[i].channel = 0; time_out[i].duration = 0; time_out[i].note = 0; time_out[i].tie_beg = 0; time_out[i].tie_end = 0; time_out[i].in_use_flag = 0; time_out[i].rest = 0; time_out[i].velocity = 0; current_preset[i] = -1; } } get_song_parameters() { register int i; MIDI_INFO *inf; char t[100]; inf = (MIDI_INFO *)&song_buffer[0x118]; for(i=1;i<16;++i) { track_info[i].channel = ((int)((inf->chan_range[i-1]) & 0x0f) - 1) & 0x0f; track_info[i].octave_num = (int)((inf->chan_range[i-1]) >> 4); track_info[i].octave = octave[track_info[i].octave_num]; track_info[i].patch = (int)(inf->patch[i-1]); /* sprintf(t,"[1][CH: %d|OCTV: %d|PTCH: %d|INDX: %d][OK]", track_info[i].channel,track_info[i].octave,track_info[i].patch,i); form_alert(1,t); */ } strcpy(song_name,inf->name); /* copy song name */ } get_note(note_str,note) int note; char note_str[]; { /* returns a formated string representing the break point */ int a,b; char tmp[5]; a = note / 12; b = note % 12; switch(b) { case 0: strcpy(note_str,"C "); break; case 1: strcpy(note_str,"C#"); break; case 2: strcpy(note_str,"D "); break; case 3: strcpy(note_str,"D#"); break; case 4: strcpy(note_str,"E "); break; case 5: strcpy(note_str,"F "); break; case 6: strcpy(note_str,"F#"); break; case 7: strcpy(note_str,"G "); break; case 8: strcpy(note_str,"G#"); break; case 9: strcpy(note_str,"A "); break; case 10: strcpy(note_str,"A#"); break; case 11: strcpy(note_str,"B "); break; } sprintf(tmp," %1d",a); strcat(note_str,tmp); } Set_Tempo() { *((char *)0xfffa1f) = tempo; } about() { OBJECT *box; int ret; rsrc_gaddr(R_TREE,ABOUT,&box); strcpy(box[ABREV].ob_spec,rev); ret = do_dialog(box,0); box[ret].ob_state = NORMAL; } init() { int i; strcpy(s_octave[0]," 0- 60"); strcpy(s_octave[1],"12- 72"); strcpy(s_octave[2],"24- 84"); strcpy(s_octave[3],"36- 96"); strcpy(s_octave[4],"48-108"); strcpy(s_octave[5],"60-120"); for(i=0;i<24;++i) { song_list[i] = NULL; /* null out song list */ song_ram[i] = NULL; song_msize[i] = 0; } } load_config(p,n) char p[]; /* path of config file */ char n[]; /* name of config file */ { FILE *config; char name[80]; int i; int num; song_index = 0; strcpy(name,p); strcat(name,n); /* make file name */ if((config = fopen(name,"r")) == NULL) return(-1); /* no config file, so just return */ fscanf(config,"%d\n",&num); /* get number of items */ for(i=0;i