home *** CD-ROM | disk | FTP | other *** search
- /* MED - music editor ⌐ 1989, 1990 by Teijo Kinnunen */
- /* med-pathlist.c: pathlist handling.. */
- #include <ctype.h>
- #include <dos.h>
- #include "med.h"
- #include "medproto.h"
- #define DIRSIZE (sizeof(struct PSDir))
- #define NAMESIZE (sizeof(struct PSName))
-
- extern struct Task *maintsk;
- extern struct Window *window;
- extern struct Kappale far song;
- extern struct Soitin *sample[];
- extern UBYTE samplenum,hakemisto[];
- extern UWORD nykyinenosio,chip mouse0[],chip mouse1[];
- extern struct RastPort *wrp;
- extern struct FData *firstfd;
- extern BPTR fh;
- static struct PSDir *firstdir = NULL,*lastdir = NULL,*dispdir = NULL;
- static struct PSName *dispname = NULL;
- static UBYTE *spaces = " ",cdirn = 0,dirs = 0;
- static UWORD centr = 0;
- UWORD lastrep,lastreplen;
- UBYTE lastmidic,lastmidip;
-
- static UWORD __regargs Getposnum(struct PSName *,struct PSName *);
- static struct PSDir * __regargs MakeNewDir(char *);
- static struct PSName * __regargs MakeNewEntry(char *);
- static void __regargs InsertSampleName(struct PSName *,struct PSDir *);
- static BOOL __regargs DirAvailable(char *);
- static void __regargs FindAvailDirs(void);
- static void __regargs RemoveDir(struct PSDir *);
- static void __regargs RemoveName(void);
- static void __regargs AddName(void);
- static void __regargs AddDir(void);
- static void __regargs GetRepVals(struct PSName *);
- static void __regargs StripRepNums(char *,char *);
- static char * __regargs SavePathFile(char *);
- static void __regargs DispEntry(UWORD);
- static BOOL __regargs SearchFromDir(struct PSDir *,char *);
- static struct PSDir * __regargs SearchDirNum(UBYTE);
- static BOOL __regargs ConstrName(char *,char *,BOOL,struct PSDir **);
-
- static UWORD __regargs Getposnum(struct PSName *ptr,struct PSName *this)
- {
- register UWORD pos = 0;
- if(!ptr || !this) return(0);
- while(ptr && ptr != this) { pos++; ptr = ptr->next; }
- return(pos);
- }
-
- static struct PSDir * __regargs MakeNewDir(char *name)
- {
- UWORD dirlen = DIRSIZE + strlen(name) + 1;
- struct PSDir *newdir = malloc(dirlen);
- if(!newdir) return(0L);
- newdir->namelen = strlen(name);
- newdir->entries = newdir->diravail = 0;
- strcpy((char *)newdir+DIRSIZE,name);
- newdir->prev = newdir->next = 0L;
- newdir->first = newdir->last = 0L;
- dirs++;
- return(newdir);
- }
-
- static struct PSName * __regargs MakeNewEntry(char *name)
- {
- UWORD entrylen = NAMESIZE + strlen(name) + 1;
- struct PSName *newentry = malloc(entrylen);
- if(!newentry) return(0L);
- newentry->namelen = strlen(name);
- newentry->firstletter = toupper(*name);
- strcpy((char *)newentry+NAMESIZE,name);
- return(newentry);
- }
-
- static void __regargs InsertSampleName(struct PSName *entr,struct PSDir *dir)
- {
- register struct PSName *first = dir->first;
- dir->entries++;
- if(!first) {
- dir->first = dir->last = entr;
- entr->next = entr->prev = 0L;
- return;
- }
- for(;stricmp((char *)first + NAMESIZE,
- (char *)entr + NAMESIZE) <= 0 && first->next;
- first = first->next);
- if(!first->next && stricmp((char *)first + NAMESIZE,
- (char *)entr + NAMESIZE) < 0) {
- entr->next = 0L;
- first->next = entr;
- entr->prev = first;
- dir->last = entr;
- return;
- }
- entr->next = first;
- if(entr->prev = first->prev) entr->prev->next = entr;
- else dir->first = entr;
- first->prev = entr;
- }
-
- static BOOL __regargs DirAvailable(char *name)
- {
- BPTR lock;
- char tstname[120];
- APTR prevwptr;
- struct Process *tpr = (struct Process *)maintsk;
- prevwptr = tpr->pr_WindowPtr;
- tpr->pr_WindowPtr = (APTR)-1;
- strcpy(tstname,name);
- if(tstname[strlen(name) - 1] == '/') tstname[strlen(name) - 1] = 0;
- lock = Lock(tstname,ACCESS_READ);
- tpr->pr_WindowPtr = prevwptr;
- if(lock) {
- UnLock(lock);
- return(TRUE);
- }
- return(FALSE);
- }
-
- static void __regargs FindAvailDirs()
- {
- struct PSDir *dir = firstdir,*dir2 = dir;
- char thisdskname[FMSIZE],cmpdskname[FMSIZE];
- while(dir2) { dir2->diravail = 2; /* 2=don't know */ dir2 = dir2->next; }
- while(dir) {
- if(dir->diravail == 2) {
- if(DirAvailable((char *)dir + DIRSIZE)) {
- dir->diravail = 1;
- strsfn((char *)dir + DIRSIZE,thisdskname,
- NULL,NULL,NULL);
- dir2 = dir->next;
- while(dir2) {
- strsfn((char *)dir2 + DIRSIZE,
- cmpdskname,NULL,NULL,NULL);
- if(!strcmp(thisdskname,cmpdskname))
- dir2->diravail = 1;
- dir2 = dir2->next; /* ^disk is available */
- }
- } else dir->diravail = 0;
- }
- dir = dir->next;
- }
- }
-
- void LoadPathFile()
- {
- UBYTE *scanptr,*pathlist;
- ULONG pathlistlen;
- BPTR fh;
- struct PSDir *currentdir;
- struct PSName *currname;
- fh = Open("MED_paths",MODE_OLDFILE);
- if(!fh) fh = Open("S:MED_paths",MODE_OLDFILE);
- if(!fh) {
- Ilmoita("MED_paths not found.");
- return; /* ei l÷ytynyt */
- }
- Seek(fh,0,OFFSET_END);
- pathlistlen = Seek(fh,0,OFFSET_BEGINNING);
- if(!(pathlist = malloc(pathlistlen))) {
- Close(fh);
- fh = NULL;
- Ilmoita("No memory for path list.");
- return;
- }
- StartLoad();
- Ilmoita("Loading MED_paths...");
- Read(fh,pathlist,pathlistlen);
- Close(fh);
- fh = NULL;
- Ilmoita("Sorting MED_paths...");
- for(scanptr = pathlist;scanptr < pathlist+pathlistlen; scanptr++)
- if(*scanptr == '\n') *scanptr = '\0';
- /* and now begin to translate the information to structures */
- scanptr = pathlist;
- while(scanptr < pathlist + pathlistlen) {
- if(*scanptr == '*') {
- if(!(currentdir = MakeNewDir(scanptr+1))) goto lpferr;
- if(!firstdir) firstdir = lastdir = currentdir;
- else {
- lastdir->next = currentdir;
- currentdir->prev = lastdir;
- lastdir = currentdir;
- }
- scanptr += strlen(scanptr+1) + 1;
- }
- else if(currentdir) {
- if(!(currname = MakeNewEntry(scanptr))) goto lpferr;
- InsertSampleName(currname,currentdir);
- scanptr += strlen(scanptr);
- }
- scanptr++;
- }
- lpferr: free(pathlist);
- dispdir = firstdir;
- if(firstdir) dispname = firstdir->first;
- StopLoad();
- Ilmoita(NULL);
- return;
- }
-
- static void __regargs AddDir()
- {
- struct PSDir *newdir;
- struct PSName *newname;
- struct FData *scanptr;
- char newdirname[FMSIZE],fc;
- strcpy(newdirname,hakemisto);
- if(!(fc = strlen(newdirname))) return;
- fc = newdirname[fc - 1];
- if(fc != ':') strcat(newdirname,"/");
- if(!(newdir = MakeNewDir(newdirname))) return;
- newdir->next = dispdir;
- if(dispdir) {
- if(dispdir->prev) {
- newdir->prev = dispdir->prev;
- dispdir->prev->next = newdir;
- }
- dispdir->prev = newdir;
- }
- if(firstdir == dispdir) firstdir = newdir;
- dispdir = newdir;
- dirs++;
- for(scanptr = firstfd; scanptr; scanptr = scanptr->next) {
- if(scanptr->type > 0) continue;
- if(!(newname = MakeNewEntry(scanptr->fname))) break;
- InsertSampleName(newname,newdir);
- }
- cdirn = Getposnum((struct PSName *)firstdir,(struct PSName *)dispdir);
- dispname = dispdir ? dispdir->first : 0L;
- centr = 0;
- DisplayPathList();
- DisplayDirName();
- }
-
- static char * __regargs SavePathFile(char *name)
- {
- struct PSDir *wrdir = firstdir;
- struct PSName *wrname;
- char *wptr,wsiz;
- if(!firstdir) return("No path list!!");
- if(!(fh = Open2(name,MODE_NEWFILE))) return(DISKERR);
- Ilmoita("Saving path list...");
- while(wrdir) {
- wptr = (char *)wrdir + DIRSIZE;
- wsiz = strlen(wptr);
- if(Write(fh,"*",1) != 1) return(DISKERR);
- if(Write(fh,wptr,wsiz) != wsiz) return(DISKERR);
- if(Write(fh,"\n",1) != 1) return(DISKERR);
- wrname = wrdir->last;
- while(wrname) { /* write in Z - A order: it's faster to load */
- wptr = (char *)wrname + NAMESIZE;
- wsiz = strlen(wptr);
- if(Write(fh,wptr,wsiz) != wsiz) return(DISKERR);
- if(Write(fh,"\n",1) != 1) return(DISKERR);
- wrname = wrname->prev;
- }
- wrdir = wrdir->next;
- }
- if(fh) { Close(fh); fh = 0L; }
- Ilmoita("Saved.");
- return(NOERR);
- }
-
- static void __regargs RemoveDir(struct PSDir *dir)
- {
- struct PSName *delname,*del2;
- if(!dir) return;
- delname = dir->first;
- if(dir->next) dir->next->prev = dir->prev;
- if(dir->prev) dir->prev->next = dir->next;
- if(firstdir == dir) firstdir = dir->next;
- dirs--;
- if(dispdir == dir)
- if(dispdir = (dir->next ? dir->next : dir->prev))
- dispname = dispdir->first;
- else dispname = 0L;
- while(delname) {
- del2 = delname->next;
- free((char *)delname);
- delname = del2;
- }
- free((char *)dir);
- cdirn = Getposnum((struct PSName *)firstdir,(struct PSName *)dispdir);
- }
-
- void FreePaths()
- {
- struct PSDir *deldir = firstdir,*ndeld;
- Ilmoita("Freeing path list...");
- while(deldir) {
- ndeld = deldir->next;
- RemoveDir(deldir);
- deldir = ndeld;
- }
- }
-
- static void __regargs AddName()
- {
- char newentry[100],*ptr;
- struct PSName *newname;
- struct SongSample *ss = &song.sample[samplenum];
- if(!dispdir) return;
- ptr = stpcpy(newentry,ss->sname);
- if(ss->midich) {
- *ptr++ = ':'; *ptr++ = ':'; *ptr++ = 'M';
- ptr += stcu_d(ptr,ss->midich);
- *ptr++ = '/';
- ptr += stcu_d(ptr,ss->midipreset);
- } else if(ss->rep || ss->replen > 1) {
- *ptr++ = ':'; *ptr++ = ':';
- ptr += stcu_d(ptr,ss->rep << 1);
- *ptr++ = '/';
- stcu_d(ptr,ss->replen << 1);
- }
- if(!(newname = MakeNewEntry(newentry))) return;
- InsertSampleName(newname,dispdir);
- dispname = newname;
- DisplayPathList();
- }
-
- static void __regargs RemoveName()
- {
- struct PSDir *remdir = dispdir;
- struct PSName *remptr = dispname;
- if(!remptr || !remdir) return;
- if(remptr->prev) remptr->prev->next = remptr->next;
- if(remptr->next) {
- remptr->next->prev = remptr->prev;
- dispname = remptr->next;
- } else dispname = remptr->prev;
- remdir->entries--;
- if(remdir->first == remptr) remdir->first = remptr->next;
- if(remdir->last == remptr) remdir->last = remptr->prev;
- free((char *)remptr);
- centr = Getposnum(remdir->first,dispname);
- }
-
- void DisplayDirName()
- {
- UBYTE txt[2] = { '0','0' },*dspdirn,*dspdirs,ddnl;
- if(nykyinenosio != 0xB) return;
- SetAPen(wrp,1);
- SetBPen(wrp,3);
- Move(wrp,147,26);
- if(!dispdir) {
- Text(wrp,"----------",10);
- txt[0] = txt[1] = '-';
- } else {
- dspdirs = dspdirn = (char *)dispdir + DIRSIZE;
- dspdirn += strlen(dspdirn) - 2;
- while(dspdirn >= dspdirs && *dspdirn != '/' && *dspdirn != ':')
- dspdirn--;
- dspdirn++;
- if((ddnl = strlen(dspdirn)) >= 10)
- Text(wrp,dspdirn,10);
- else {
- Text(wrp,dspdirn,ddnl);
- Text(wrp,spaces,10 - ddnl);
- }
- }
- Move(wrp,211,37);
- txt[0] += cdirn /á10;
- txt[1] += cdirn % 10;
- Text(wrp,txt,2);
- }
-
- void DisplayPathList()
- {
- struct PSName *dptr;
- UBYTE dispcnt;
- if(nykyinenosio != 0xB) return;
- SetAPen(wrp,0);
- SetBPen(wrp,3);
- wrp->Mask = 0x3;
- if(!dispname || !dispdir) for(dispcnt = 0; dispcnt < 5; dispcnt++) {
- Move(wrp,7,26 + 8 * dispcnt);
- Text(wrp,spaces,16);
- } else for(dispcnt = 0; dispcnt < 5; dispcnt++) {
- Move(wrp,7,26 + 8 * dispcnt);
- switch(dispcnt) {
- case 0: if(dptr = dispname->prev) dptr = dptr->prev;
- break;
- case 1: dptr = dispname->prev; break;
- case 2: dptr = dispname; SetBPen(wrp,1); break;
- case 3: dptr = dispname->next; SetBPen(wrp,3); break;
- case 4: if(dptr = dispname->next) dptr = dptr->next;
- }
- if(!dptr) Text(wrp,spaces,16);
- else {
- if(dptr->namelen >= 16) Text(wrp,(char *)dptr +
- NAMESIZE,16);
- else {
- Text(wrp,(char *)dptr + sizeof(struct
- PSName),dptr->namelen);
- Text(wrp,spaces,16 - dptr->namelen);
- }
- dptr = dptr->next;
- }
- }
- wrp->Mask = 0xff;
- }
-
- static void __regargs GetRepVals(struct PSName *name)
- {
- UBYTE *tstchr,midi = 0;
- ULONG rvals[2] = { 0,0 },*numptr = rvals;
- if(!name) return;
- lastrep = lastreplen = 0;
- lastmidic = lastmidip = 0;
- tstchr = (UBYTE *)name + NAMESIZE;
- while(*tstchr && *tstchr != ':') tstchr++;
- if(!(*tstchr) || *(tstchr+1) != ':') return;
- tstchr += 2;
- if(*tstchr == 'm' || *tstchr == 'M') { midi = 1; tstchr++; }
- while(*tstchr) {
- if(*tstchr == '/') numptr = &rvals[1]; /* now coming length */
- if(isdigit(*tstchr)) {
- *numptr *= 10;
- *numptr += ((*tstchr) - '0');
- }
- tstchr++;
- }
- if(midi) { /* these numbers are not repeat/length, instead they */
- /* are now midi channel and preset number */
- if(lastrep <= 16) lastmidic = (UBYTE)rvals[0];
- if(lastreplen <= 128) lastmidip = (UBYTE)rvals[1];
- } else {
- lastrep = (UWORD)(rvals[0] >> 1);
- lastreplen = (UWORD)(rvals[1] >> 1);
- }
- }
-
- static void __regargs StripRepNums(char *name,char *to)
- {
- while(*name && *name != ':') *to++ = *name++;
- *to = 0;
- }
-
- void LoadSelectedSample()
- {
- char fullname[150],*nameptr;
- if(!dispname || !dispdir) return;
- StartLoad();
- strcpy(fullname,(char *)dispdir + DIRSIZE);
- nameptr = fullname + strlen(fullname);
- StripRepNums((char *)dispname + NAMESIZE,nameptr);
- GetRepVals(dispname);
- strcpy(song.sample[samplenum].sname,nameptr);
- nameptr = LoadInstrument(fullname,FALSE);
- PaivitaSoittimennimi();
- StopLoad();
- if(nameptr == NOERR) SampleLoaded();
- diskerr(nameptr);
- }
-
- static void __regargs DispEntry(UWORD num)
- {
- dispname = dispdir->first;
- centr = 0;
- while(num-- && dispname->next) { dispname = dispname->next; centr++; }
- DisplayPathList();
- }
-
- void ScrollSLUp(BYTE steps)
- {
- if(!dispname) return;
- if(steps < 0) {
- dispname = dispdir->first;
- centr = 0;
- }
- else while(centr && steps--) { dispname = dispname->prev; centr--; }
- DisplayPathList();
- }
-
- void ScrollSLDown(BYTE steps)
- {
- if(!dispname) return;
- if(steps < 0) {
- dispname = dispdir->last;
- centr = dispdir->entries - 1;
- } else while(centr < (dispdir->entries - 1) && steps--) {
- dispname = dispname->next; centr++;
- }
- DisplayPathList();
- }
-
- void HandleB(UWORD gid)
- {
- switch(gid) {
- case 0xB00: ScrollSLUp(1); break;
- case 0xB02: ScrollSLDown(1); break;
- case 0xB03: case 0xB04:
- if(!dispdir) break;
- if(gid == 0xB03) {
- if(dispdir->prev) {
- dispdir = dispdir->prev;
- cdirn--;
- }
- } else {
- if(dispdir->next) {
- dispdir = dispdir->next;
- cdirn++;
- }
- }
- dispname = dispdir->first;
- centr = 0;
- DisplayPathList();
- DisplayDirName();
- break;
- case 0xB01: ScrollSLUp((BYTE)-1); break;
- case 0xB0C: ScrollSLDown((BYTE)-1); break;
- case 0xB05: LoadSelectedSample(); break;
- case 0xB0A: RemoveName(); DisplayPathList(); break;
- case 0xB0B: RemoveDir(dispdir);
- DisplayPathList(); DisplayDirName(); break;
- case 0xB08: AddName(); break;
- case 0xB09: AddDir(); break;
- case 0xB06: case 0xB07:
- StartLoad();
- diskerr(SavePathFile(gid == 0xB06 ? "MED_paths" :
- "S:MED_paths"));
- StopLoad();
- }
- }
-
- static BOOL __regargs SearchFromDir(struct PSDir *dir,char *name)
- {
- UBYTE matchletter = toupper(*name),name2[110];
- struct PSName *searchptr = (dir ? dir->first : 0L);
- while(searchptr) {
- if(searchptr->firstletter >= matchletter) {
- if(searchptr->firstletter > matchletter) return(FALSE);
- StripRepNums((char *)searchptr+NAMESIZE,name2);
- if(!stricmp(name2,name)) {
- GetRepVals(searchptr);
- return(TRUE);
- }
- }
- searchptr = searchptr->next;
- }
- return(FALSE);
- }
-
- static struct PSDir * __regargs SearchDirNum(UBYTE num)
- {
- struct PSDir *ptr = firstdir;
- while(ptr && num--) ptr = ptr->next;
- return(ptr);
- }
-
- static BOOL __regargs ConstrName(char *fname,char *tname,
- BOOL mustfind,struct PSDir **founddir)
- {
- UBYTE dircnt;
- char fpath[FMSIZE];
- struct PSDir *tstdir,*found = 0L;
- *tname = 0;
- *founddir = 0L;
- if(stcgfp(fpath,fname)) {
- if(DirAvailable(fpath) || mustfind) {
- strcpy(tname,fname);
- return(TRUE);
- }
- return(FALSE);
- }
- for(dircnt = 0; dircnt < dirs; dircnt++) {
- tstdir = SearchDirNum(dircnt);
- if(tstdir->diravail && SearchFromDir(tstdir,fname)) {
- found = tstdir;
- break;
- }
- }
- if(mustfind && !found) {
- for(dircnt = 0; dircnt < dirs; dircnt++) {
- tstdir = SearchDirNum(dircnt);
- if(!tstdir->diravail && SearchFromDir(tstdir,fname)) {
- found = tstdir;
- break;
- }
- }
- }
- if(found) strcpy(tname,(char *)found + DIRSIZE);
- *founddir = found;
- strcat(tname,fname);
- return((BOOL)found);
- }
-
- void ConstructDirName(char *from,char *to)
- {
- struct PSDir *dir = firstdir,*here = NULL;
- while(dir) {
- if(SearchFromDir(dir,from)) {
- here = dir;
- if(DirAvailable((char *)dir + DIRSIZE)) break;
- }
- dir = dir->next;
- }
- if(here) strcpy(to,(char *)here + DIRSIZE);
- else *to = '\0';
- strcat(to,from);
- }
-
- char *LoadSongSamples() /* the intelligent sample loader */
- {
- UBYTE samplelist[63],cnt,stl = 0,fullname[FMSIZE];
- char *res = NOERR;
- struct PSDir *dir;
- FindAvailDirs();
- for(cnt = 0; cnt < 63; cnt++) /* Find number of samples to load */
- if(song.sample[cnt].sname[0] && !song.sample[cnt].midich
- && !sample[cnt] && stcgfn(fullname,song.sample[cnt].sname)) {
- samplelist[cnt] = 1;
- stl++;
- } else samplelist[cnt] = 0;
- while(stl) {
- for(cnt = 0; cnt < 63; cnt++) {
- if(samplelist[cnt] == 1) {
- if(ConstrName(song.sample[cnt].sname,
- /* load everything that can be */ fullname,FALSE,&dir)) {
- /* loaded without disk swapping */ samplenum = cnt;
- PaivitaSoittimennimi();
- stl--;
- samplelist[cnt] = 0;
- if(res = LoadInstrument(fullname,FALSE)) {
- diskerr(res);
- if(!Continue()) goto stop;
- }
- }
- }
- }
- for(cnt = 0; cnt < 63; cnt++) {
- if(samplelist[cnt] == 1) {
- /* then load a sample which */ ConstrName(song.sample[cnt].sname,
- /* needs disk swapping */ fullname,TRUE,&dir);
- samplenum = cnt;
- PaivitaSoittimennimi();
- stl--;
- samplelist[cnt] = 0;
- if(res = LoadInstrument(fullname,FALSE)) {
- diskerr(res);
- if(!Continue()) goto stop;
- }
- if(dir) dir->diravail = 1;
- /* try again load without.. */ break; /* ..swapping */
- }
- }
- }
- return(NOERR);
- stop: return("Loading aborted.");
- }
-