/* Name: MIKCVT.C Description: Program to convert any module into a .UNI module Portability: All systems - all compilers */ package audio.jmikmod.MikMod; import java.io.IOException; import persist.SimulatedRandomAccessFile; import audio.jmikmod.MikMod.Loaders.M15_Loader; import audio.jmikmod.MikMod.Loaders.MOD_Loader; import audio.jmikmod.MikMod.Loaders.MTM_Loader; import audio.jmikmod.MikMod.Loaders.S3M_Loader; import audio.jmikmod.MikMod.Loaders.S69_Loader; import audio.jmikmod.MikMod.Loaders.STM_Loader; import audio.jmikmod.MikMod.Loaders.ULT_Loader; import audio.jmikmod.MikMod.Loaders.UNI_Loader; import audio.jmikmod.MikMod.Loaders.XM_Loader; import audio.jmikmod.MikMod.MUniTrk.clMUniTrk; class clMikCvtMDriver extends clMDriverBase { public clMikCvtMain m_; public clMikCvtMDriver(clMikCvtMain theMain) { super(theMain); m_ = theMain; } public short MD_SampleLoad(SimulatedRandomAccessFile fp, int length, int loopstart, int loopend, int flags) { /* record position of sample */ try { m_.samplepos[m_.numsamples] = (int)fp.getFilePointer(); /* determine it's bytesize */ if ((flags & SF_16BITS) != 0) length <<= 1; /* record bytesize and skip the sample */ m_.samplesize[m_.numsamples++] = length; fp.seek(length+fp.getFilePointer()); } catch (IOException ioe1) {} return 1; } public void MD_SampleUnLoad(short handle) {} }; public class clMikCvtMain extends clMainBase { public SimulatedRandomAccessFile fpi, fpo; public short numsamples; public int samplepos[]; public int samplesize[]; public byte buf[]; public clMikCvtMDriver MDriver; public clMikCvtMain() { samplepos = new int[128]; samplesize = new int[128]; buf = new byte[8000]; } int CopyData(SimulatedRandomAccessFile fpi, SimulatedRandomAccessFile fpo, int len) { int todo; try { while (len != 0) { todo = (len > 8000) ? 8000 : len; //if (!fread(buf, todo, 1, fpi)) if (fpi.read(buf,0,todo) != todo) return 0; //fwrite(buf, todo, 1, fpo); fpo.write(buf, 0, todo); len -= todo; } } catch (IOException ioe1) {} return 1; } /*************************************************************************** **************************************************************************** ***************************************************************************/ boolean TrkCmp(short t1[], short t2[]) { int l1, l2; if (t1 == null || t2 == null) return false; l1 = MUniTrk.TrkLen(t1); l2 = MUniTrk.TrkLen(t2); if (l1 != l2) return false; return (MUniTrk.MyCmp(t1, 0, t2, 0, l1)); } void ReplaceTrack(UNIMOD mf, int t1, int t2) { int t; for (t = 0; t < mf.numpat * mf.numchn; t++) { if (mf.patterns[t] == t1) mf.patterns[t] = (short)t2; } } void Optimize(UNIMOD mf) /* Optimizes the number of tracks in a modfile by removing tracks with identical contents. */ { int t, u, done = 0, same, newcnt = 0; short ta[]; short newtrk[][]; //if (!(newtrk = (short**)malloc(mf.numtrk * sizeof(short *)))) // return; newtrk = new short [mf.numtrk][]; if (newtrk == null) return; for (t = 0; t < mf.numtrk; t++) { /* ta is track to examine */ ta = mf.tracks[t]; /* does ta look familiar ? */ for (same = u = 0; u < newcnt; u++) { if (TrkCmp(ta, newtrk[u])) { same = 1; break; } } if (same != 0) { ReplaceTrack(mf, t, u); done++; } else { ReplaceTrack(mf, t, newcnt); newtrk[newcnt++] = ta; } //printf("\rOptimizing: %d\r", (t * 100L) / mf.numtrk); System.out.print("\rOptimizing: " + (int)((t * 100L) / mf.numtrk) + "\r"); } //printf("\rOptimized : %d tracks\n", done); System.out.print("\rOptimized : " + done + " tracks\n"); mf.tracks = null; mf.tracks = newtrk; mf.numtrk = (short)newcnt; } /*************************************************************************** **************************************************************************** ***************************************************************************/ void StrWrite(String s) /* Writes a null-terminated string as a pascal string to fpo. */ { int len; try { len = (s != null) ? s.length() : 0; mmIO._mm_write_I_UWORD(len, fpo); if (len != 0) { byte buf[] = new byte[len]; s.getBytes(0, len, buf, 0); //fwrite(buf, len, 1, fpo); fpo.write(buf,0,len); buf = null; } } catch (IOException ioe1) {} } void TrkWrite(short t[]) /* Writes a track to fpo. */ { int len; if (t == null) System.out.print("NULL track"); len = MUniTrk.TrkLen(t); mmIO._mm_write_I_UWORD(len, fpo); //fwrite(t, len, 2, fpo); mmIO._mm_write_UBYTES2(t,len,fpo); } String stripname(String path, String ext) /* Strips the filename from a path, and replaces or adds a new extension to it. */ { //char *n, *m; int n, m; //static char newname[256]; String newname; /* extract the filename from the path */ /*#ifdef unix n = ((n = strrchr(path, '/')) == NULL) ? path : n + 1; #else n = ((n = strrchr(path, '\\')) == NULL) ? path : n + 1; if(m = strrchr(n, ':')) n=m+1; #endif*/ /*#ifdef unix n = ((n = path.lastIndexOf('/')) == -1) ? 0 : n + 1; #else n = ((n = path.lastIndexOf('\\')) == -1) ? 0 : n + 1; if ((m = path.lastIndexOf(':', n)) != -1) n = m+1; #endif*/ n = ( (n = path.lastIndexOf(System.getProperties().getProperty("file.separator")) ) == -1) ? 0 : n + 1; /* copy the filename into 'newname' */ //strncpy(newname,n,255); //newname[255]=0; newname = path.substring(n); /* remove the extension */ //if (n = strrchr(newname, '.')) //*n = 0; if ((n = newname.lastIndexOf('.')) != -1) { newname = newname.substring(0, n); } newname = newname + ext; /* and tack on the new extension */ //return strcat(newname, ext); return newname; } /*int main(int argc, char *argv[]) { clMikCvtMain main_class; main_class.main(argc,argv); }*/ public int main(String argv[]) { int t, v, w; int argc = argv.length; String outname; //System.out.print(mikbanner); try { /* Expand wildcards on commandline (NoT on unix systems please): */ /*#ifndef unix MyGlob(&argc, &argv, 0); #endif*/ MLoader = new audio.jmikmod.MikMod.MLoader.clMLoader(this); MUniTrk = new clMUniTrk(this); mmIO = new audio.jmikmod.MikMod.MMIO.MMIO(this); mmIO._mm_setiobase(0); MDriver = new clMikCvtMDriver(this); super.MDriver = MDriver; Display = new clDisplayBase(this); /* Register the loaders we want to use.. */ M15_Loader cl_load_m15 = new audio.jmikmod.MikMod.Loaders.M15_Loader(this); MLoader.ML_RegisterLoader(cl_load_m15); MOD_Loader cl_load_mod = new audio.jmikmod.MikMod.Loaders.MOD_Loader(this); MLoader.ML_RegisterLoader(cl_load_mod); MTM_Loader cl_load_mtm = new audio.jmikmod.MikMod.Loaders.MTM_Loader(this); MLoader.ML_RegisterLoader(cl_load_mtm); S3M_Loader cl_load_s3m = new audio.jmikmod.MikMod.Loaders.S3M_Loader(this); MLoader.ML_RegisterLoader(cl_load_s3m); STM_Loader cl_load_stm = new audio.jmikmod.MikMod.Loaders.STM_Loader(this); MLoader.ML_RegisterLoader(cl_load_stm); ULT_Loader cl_load_ult = new audio.jmikmod.MikMod.Loaders.ULT_Loader(this); MLoader.ML_RegisterLoader(cl_load_ult); UNI_Loader cl_load_uni = new audio.jmikmod.MikMod.Loaders.UNI_Loader(this); MLoader.ML_RegisterLoader(cl_load_uni); S69_Loader cl_load_669 = new audio.jmikmod.MikMod.Loaders.S69_Loader(this); MLoader.ML_RegisterLoader(cl_load_669); XM_Loader cl_load_xm = new audio.jmikmod.MikMod.Loaders.XM_Loader(this); MLoader.ML_RegisterLoader(cl_load_xm); if (argc < 2) { /* display a usage message */ System.out.println("Usage: MIKCVT <fletch.mod> ... "); System.out.println("Converts your modules to .UNI modules\n"); return -1; } for (t = 1; t < argc; t++) { UNIMOD mf; //printf("In file : %s\n", argv[t]); System.out.println("In file : " + argv[t] + "\n"); numsamples = 0; //if ((fpi = fopen(argv[t], "rb")) == null) { if ((fpi = new SimulatedRandomAccessFile(argv[t])) == null) { System.out.println("MikCvt Error: Error opening input file"); break; } outname = stripname(argv[t], ".uni"); //printf("Out file: %s\n", outname); System.out.println("Out file: " + outname); //if ((fpo = fopen(outname, "wb")) == null) { if ((fpo = new SimulatedRandomAccessFile(outname)) == null) { System.out.println("MikCvt Error: Error opening output file"); break; } mf = MLoader.ML_LoadFP(fpi); /* didn't work . exit with error */ if (mf == null) { System.out.println("MikCvt Error: " + mmIO.myerr); //fclose(fpi); fpi.close(); fpi = null; break; } /* Optimize the tracks */ Optimize(mf); /* Write UNI header */ //fwrite("UN05", 4, 1, fpo); long mypos=0; { byte uno5_buf[] = new byte[4]; String uno5_str = "UN05"; uno5_str.getBytes(0,4,uno5_buf, 0); fpo.write(uno5_buf,0,4); } mypos = fpo.getFilePointer(); mmIO._mm_write_UBYTE(mf.numchn, fpo); mypos = fpo.getFilePointer(); mmIO._mm_write_I_UWORD(mf.numpos, fpo); mypos = fpo.getFilePointer(); mmIO._mm_write_I_UWORD(mf.reppos, fpo); mypos = fpo.getFilePointer(); mmIO._mm_write_I_UWORD(mf.numpat, fpo); mypos = fpo.getFilePointer(); mmIO._mm_write_I_UWORD(mf.numtrk, fpo); mmIO._mm_write_I_UWORD(mf.numins, fpo); mmIO._mm_write_UBYTE(mf.initspeed, fpo); mmIO._mm_write_UBYTE(mf.inittempo, fpo); mmIO._mm_write_UBYTES2(mf.positions, 256, fpo); mmIO._mm_write_UBYTES2(mf.panning, 32, fpo); mmIO._mm_write_UBYTE(mf.flags, fpo); mypos = fpo.getFilePointer(); StrWrite(mf.songname); StrWrite(mf.modtype); StrWrite(mf.comment); /* Write instruments */ mypos = fpo.getFilePointer(); for (v = 0; v < mf.numins; v++) { //INSTRUMENT *i = &mf.instruments[v]; mypos = fpo.getFilePointer(); mmIO._mm_write_UBYTE(mf.instruments[v].numsmp, fpo); mmIO._mm_write_UBYTES2(mf.instruments[v].samplenumber, 96, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].volflg, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].volpts, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].volsus, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].volbeg, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].volend, fpo); for (w = 0; w < 12; w++) { mmIO._mm_write_I_SWORD(mf.instruments[v].volenv[w].pos, fpo); mmIO._mm_write_I_SWORD(mf.instruments[v].volenv[w].val, fpo); } mmIO._mm_write_UBYTE(mf.instruments[v].panflg, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].panpts, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].pansus, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].panbeg, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].panend, fpo); for (w = 0; w < 12; w++) { mmIO._mm_write_I_SWORD(mf.instruments[v].panenv[w].pos, fpo); mmIO._mm_write_I_SWORD(mf.instruments[v].panenv[w].val, fpo); } mmIO._mm_write_UBYTE(mf.instruments[v].vibtype, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].vibsweep, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].vibdepth, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].vibrate, fpo); mmIO._mm_write_I_UWORD(mf.instruments[v].volfade, fpo); StrWrite(mf.instruments[v].insname); for (w = 0; w < mf.instruments[v].numsmp; w++) { //SAMPLE *s = &mf.instruments[v].samples[w]; mmIO._mm_write_I_UWORD(mf.instruments[v].samples[w].c2spd, fpo); mmIO._mm_write_SBYTE(mf.instruments[v].samples[w].transpose, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].samples[w].volume, fpo); mmIO._mm_write_UBYTE(mf.instruments[v].samples[w].panning, fpo); mmIO._mm_write_I_ULONG(mf.instruments[v].samples[w].length, fpo); mmIO._mm_write_I_ULONG(mf.instruments[v].samples[w].loopstart, fpo); mmIO._mm_write_I_ULONG(mf.instruments[v].samples[w].loopend, fpo); mmIO._mm_write_I_UWORD(mf.instruments[v].samples[w].flags, fpo); StrWrite(mf.instruments[v].samples[w].samplename); } } mypos = fpo.getFilePointer(); /* Write patterns */ mmIO._mm_write_I_UWORDS2(mf.pattrows, mf.numpat, fpo); mmIO._mm_write_I_SWORDS(mf.patterns, mf.numpat * mf.numchn, fpo); mypos = fpo.getFilePointer(); /* Write tracks */ for (v = 0; v < mf.numtrk; v++) { TrkWrite(mf.tracks[v]); } System.out.print("Writing samples.. "); mypos = fpo.getFilePointer(); /* Write sample-data */ for (v = 0; v < numsamples; v++) { //fseek(fpi, samplepos[v], SEEK_SET); fpi.seek(samplepos[v]); CopyData(fpi, fpo, samplesize[v]); mypos = fpo.getFilePointer(); } mypos = fpo.getFilePointer(); System.out.print("Done."); /* and clean up */ //fclose(fpo); //fclose(fpi); fpo.close(); fpo = null; fpi.close(); fpi = null; MLoader.ML_Free(mf); } } catch (IOException ioe1) {} return 0; } }