/* Name: MLOADER.C Description: These routines are used to access the available module loaders Portability: All systems - all compilers */ package audio.jmikmod.MikMod.MLoader; import java.io.*; import java.net.URISyntaxException; import java.net.URL; import persist.SimulatedRandomAccessFile; import audio.jmikmod.MikMod.*; public class clMLoader extends Object { //public final short finetune[16] = { public final short finetune[] = { 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757, 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280 }; public clMainBase m_; public SimulatedRandomAccessFile modfp; public UNIMOD of; //clLOADER *firstloader; //=NULL; //public clLOADER loaders[16]; public clLOADER loaders[]; public int num_loaders; public clMLoader(clMainBase theMain) { m_ = theMain; num_loaders = 0; loaders = new clLOADER[16]; of = new UNIMOD(); } public void ML_InfoLoader() { int t; /* list all registered devicedrivers: */ for (t=0;t<num_loaders;t++) //printf("%d. %s\n",t+1,(const char *)(*loaders[num_loaders-1-t]->version)); //puts((t+1) + String(". ") + loaders[num_loaders-1-t].version); System.out.println((t+1) + ". " + loaders[num_loaders-1-t].version); } public void ML_RegisterLoader(clLOADER ldr) { loaders[num_loaders] = ldr; num_loaders++; } public boolean ReadComment(short len) throws IOException { int t; if(len != 0){ byte [] buf; if((buf=new byte[len+1]) == null) return false; //fread(buf,len,1,modfp); modfp.read(buf,0,len); buf[len]=0; /* strip any control-characters in the comment: */ for(t=0;t<len;t++){ if(buf[t]<32) buf[t]=' '; } of.comment = new String(buf,0,0,len); buf = null; } return true; } public boolean AllocPatterns() { int s,t,tracks=0; /* Allocate track sequencing array */ //if(!(of.patterns=(short *)MyCalloc((int)of.numpat*of.numchn,sizeof(short)))) return 0; of.patterns = new short [(int)of.numpat*of.numchn]; for(t=0 ; t < (int)of.numpat*of.numchn ; t++) of.patterns[t] = 0; //if(!(of.pattrows=(int *)MyCalloc(of.numpat,sizeof(int)))) return 0; of.pattrows = new int [of.numpat]; for(t=0 ; t < of.numpat ; t++) of.pattrows[t] = 0; for(t=0;t<of.numpat;t++){ of.pattrows[t]=64; for(s=0;s<of.numchn;s++){ of.patterns[(t*of.numchn)+s]=(short)(tracks++); } } return true; } public boolean AllocTracks() { //if(!(of.tracks=(short **)MyCalloc(of.numtrk,sizeof(short *)))) return 0; int i; of.tracks = new short [of.numtrk][]; for(i=0; i<of.numtrk; i++) of.tracks[i] = null; return true; } public boolean AllocInstruments() { //if(!(of.instruments=(INSTRUMENT *)MyCalloc(of.numins,sizeof(INSTRUMENT)))) return 0; int i,j; of.instruments = new INSTRUMENT [of.numins]; for(i=0; i<of.numins; i++) { of.instruments[i] = new INSTRUMENT(); } for(i=0; i<of.numins; i++) { of.instruments[i].numsmp = of.instruments[i].volflg = of.instruments[i].volpts = of.instruments[i].volsus = of.instruments[i].volbeg = of.instruments[i].volend = of.instruments[i].panflg = of.instruments[i].pansus = of.instruments[i].panend = of.instruments[i].vibtype = of.instruments[i].vibsweep = of.instruments[i].vibdepth = of.instruments[i].vibrate = (short)0; of.instruments[i].volfade = 0; of.instruments[i].insname = null; of.instruments[i].samples = null; for(j=0;j<96;j++) of.instruments[i].samplenumber[j] = 0; for(j=0;j<12;j++) { of.instruments[i].volenv[j].pos = of.instruments[i].volenv[j].val = of.instruments[i].panenv[j].pos = of.instruments[i].panenv[j].val = 0; } } return true; } public boolean AllocSamples(INSTRUMENT i) { int u,n; if((n=i.numsmp) != 0) { //if(!(i->samples=(SAMPLE *)MyCalloc(n,sizeof(SAMPLE)))) return 0; i.samples = new SAMPLE[n]; for(u=0;u<n;u++) { i.samples[u] = new SAMPLE(); } for(u=0;u<n;u++) { i.samples[u].c2spd = i.samples[u].length = i.samples[u].loopstart = i.samples[u].loopend = i.samples[u].flags = i.samples[u].seekpos = i.samples[u].handle = 0; i.samples[u].transpose = (byte)0; i.samples[u].volume = i.samples[u].panning = (short)0; i.samples[u].samplename = null; } for(u=0; u<n; u++){ i.samples[u].panning=128; i.samples[u].handle=-1; } } return true; } public String DupStr(byte s[],short len) { short t; byte d[]; /* Scan for first printing char in buffer [includes high ascii up to 254] */ while(len != 0){ if(!(s[len-1]>=0 && s[len-1]<=0x20)) break; len--; } if(len != 0){ /* When the buffer wasn't completely empty, allocate a cstring and copy the buffer into that string, except for any control-chars */ if((d=new byte[len+1])!=null){ for(t=0;t<len;t++) { d[t]=((s[t]>=0 && s[t]<32) ? ((byte)' '): s[t]); } d[t]=0; } String sPtr = new String(d, 0, 0, len); d = null; return sPtr; } return new String(); } // To avoid lots of casting errors public String DupStr(byte s[],int len) { return DupStr(s, (short)len); } public boolean ML_LoadSamples() { int t,u; //INSTRUMENT *i; //SAMPLE *s; for(t=0;t<of.numins;t++){ //i=&of.instruments[t]; for(u=0; u<of.instruments[t].numsmp; u++){ //s=&of.instruments[t].samples[u]; /* printf("Loading Sample %d\n",t); */ /* sample has to be loaded ? -> increase number of samples and allocate memory and load sample */ if(of.instruments[t].samples[u].length != 0){ if(of.instruments[t].samples[u].seekpos != 0){ m_.mmIO._mm_fseek(modfp,of.instruments[t].samples[u].seekpos,m_.mmIO.SEEK_SET); } /* Call the sample load routine of the driver module. It has to return a 'handle' (>=0) that identifies the sample */ of.instruments[t].samples[u].handle=m_.MDriver.MD_SampleLoad(modfp, of.instruments[t].samples[u].length, of.instruments[t].samples[u].loopstart, of.instruments[t].samples[u].loopend, of.instruments[t].samples[u].flags); if(of.instruments[t].samples[u].handle<0) return false; } } } return true; } public boolean ML_LoadHeader() { boolean ok=false; //clLOADER *l; int t; /* Try to find a loader that recognizes the module */ /*for(l=firstloader; l!=NULL; l=l.next){ m_.mmIO._mm_rewind(modfp); if(l.Test()) break; }*/ for(t=num_loaders-1; t >= 0; t--){ m_.mmIO._mm_rewind(modfp); //l=loaders[t]; if(loaders[t].Test()) break; } if(t == -1){ m_.mmIO.myerr="Unknown module format"; m_.mmIO.myerr_file=m_.cur_mod.filename.getFile(); return false; } /* init unitrk routines */ if(!m_.MUniTrk.UniInit()) return false; /* init module loader */ if(loaders[t].Init()){ m_.mmIO._mm_rewind(modfp); ok=loaders[t].Load(); } loaders[t].Cleanup(); /* free unitrk allocations */ m_.MUniTrk.UniCleanup(); return ok; } public void ML_XFreeInstrument(INSTRUMENT i) { int t; if(i.samples!=null){ for(t=0; t<i.numsmp; t++){ if(i.samples[t].handle>=0){ m_.MDriver.MD_SampleUnLoad(i.samples[t].handle); } } i.samples = null; } if(i.insname!=null) i.insname = null; } public void ML_FreeEx(UNIMOD mf) { int t; if(mf.modtype!=null) mf.modtype = null; if(mf.patterns!=null) mf.patterns = null; if(mf.pattrows!=null) mf.pattrows = null; if(mf.tracks!=null){ for(t=0;t<mf.numtrk;t++) { if(mf.tracks[t]!=null) mf.tracks[t] = null; } mf.tracks = null; } if(mf.instruments!=null){ for(t=0;t<mf.numins;t++){ ML_XFreeInstrument(mf.instruments[t]); } mf.instruments = null; } if(mf.songname!=null) mf.songname = null; if(mf.comment!=null) mf.comment = null; } /****************************************** Next are the user-callable functions ******************************************/ public void ML_Free(UNIMOD mf) { if(mf!=null){ ML_FreeEx(mf); mf = null; } } public UNIMOD ML_LoadFP(SimulatedRandomAccessFile fp) { int t; UNIMOD mf; /* init fileptr, clear errorcode, clear static modfile: */ modfp=fp; m_.mmIO.myerr=""; m_.mmIO.myerr_file=""; //memset(&of,0,sizeof(UNIMOD)); of.numchn = of.numpos = of.reppos = of.numpat = of.numtrk = of.numins = of.initspeed = of.inittempo = of.flags = 0; of.songname = of.modtype = of.comment = null; of.patterns = null; of.instruments = null; of.pattrows = null; of.tracks = null; for(t=0; t<256; t++) of.positions[t] = 0; for(t=0; t<32; t++) of.panning[t] = 0; /* init panning array */ for(t=0;t<32;t++){ of.panning[t]=(short)((((t+1)&2) != 0)?255:0); } if(!ML_LoadHeader()){ ML_FreeEx(of); return null; } if(!ML_LoadSamples()){ ML_FreeEx(of); return null; } /*if(!(mf=(UNIMOD *)MyCalloc(1,sizeof(UNIMOD)))){ ML_FreeEx(&of); return NULL; }*/ mf = new UNIMOD(); /* I removed the calloc-like nullization because it's needless in this context. */ /* Copy the static UNIMOD contents into the dynamic UNIMOD struct */ //memcpy(mf,&of,sizeof(UNIMOD)); // A simple assignment may work in C, but with Java and its crazy // references, we may get two references to the same object instead // of two distinct object instances. mf.numchn = of.numchn; mf.numpos = of.numpos; mf.reppos = of.reppos; mf.numpat = of.numpat; mf.numtrk = of.numtrk; mf.numins = of.numins; mf.initspeed = of.initspeed; mf.inittempo = of.inittempo; for(t=0; t<256; t++) mf.positions[t] = of.positions[t]; for(t=0; t<32; t++) mf.panning[t] = of.panning[t]; mf.flags = of.flags; mf.songname = of.songname; mf.modtype = of.modtype; mf.comment = of.comment; mf.instruments = of.instruments; mf.patterns = of.patterns; mf.pattrows = of.pattrows; mf.tracks = of.tracks; return mf; } public UNIMOD ML_LoadFN(URL filename) { SimulatedRandomAccessFile fp = null; UNIMOD mf; //if((fp=fopen((const char*)*filename,"rb"))==NULL){ try { try { if ( (fp = new SimulatedRandomAccessFile(filename)) == null) { m_.mmIO.myerr="Error opening file"; m_.mmIO.myerr_file=filename.getFile(); return null; } } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* display "loading" message */ m_.Display.display_version(); m_.Display.display_loadbanner(); mf=ML_LoadFP(fp); //fclose(fp); fp.close(); fp = null; return mf; } catch (IOException ioe1) { ioe1.printStackTrace(); return null; } } }