#include <stdio.h>
#include <stdlib.h>
#include <dir.h>
#include <string.h>
#include "mtypes.h"
#include "wildfile.h"
#include "mloader.h"
#include "munitrk.h"
/*
Declare external loaders:
*/
extern LOADER mtmload,s3mload,ultload,modload,dsmload,medload,
farload,s69load,uniload,xmload,stmload,m15load;
FILE *fpi,*fpo;
UWORD numsamples;
ULONG samplepos[128];
ULONG samplesize[128];
UBYTE buf[8000];
static char path[MAXPATH];
static char drive[MAXDRIVE];
static char dir[MAXDIR];
static char name[MAXFILE];
static char ext[MAXEXT];
int CopyData(FILE *fpi,FILE *fpo,ULONG len)
{
ULONG todo;
while(len){
todo=(len>8000)?8000:len;
if(!fread(buf,todo,1,fpi)) return 0;
fwrite(buf,todo,1,fpo);
len-=todo;
}
return 1;
}
/***************************************************************************
****************************************************************************
***************************************************************************/
int TrkCmp(UBYTE *t1,UBYTE *t2)
{
int l1,l2;
if(t1==NULL || t2==NULL) return 0;
l1=TrkLen(t1);
l2=TrkLen(t2);
if(l1!=l2) return 0;
return(MyCmp(t1,t2,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]=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;
UBYTE *ta;
UBYTE **newtrk;
if(!(newtrk=malloc(mf->numtrk*sizeof(UBYTE *)))) 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){
ReplaceTrack(mf,t,u);
done++;
}
else{
ReplaceTrack(mf,t,newcnt);
newtrk[newcnt++]=ta;
}
printf("\rOptimizing: %d\%",(t*100L)/mf->numtrk);
}
printf("\rOptimized : %d tracks\n",done);
free(mf->tracks);
mf->tracks=newtrk;
mf->numtrk=newcnt;
}
/***************************************************************************
****************************************************************************
***************************************************************************/
WORD MD_SampleLoad(FILE *fp,ULONG length,ULONG loopstart,ULONG loopend,UWORD flags)
{
// record position of sample
samplepos[numsamples]=ftell(fp);
// determine it's bytesize
if(flags&SF_16BITS) length<<=1;
// record bytesize and skip the sample
samplesize[numsamples++]=length;
fseek(fp,length,SEEK_CUR);
return 1;
}
void MD_SampleUnLoad(WORD handle)
{
}
void StrWrite(char *s)
/*
Writes a null-terminated string as a pascal string to fpo.
*/
{
int len;
len=(s!=NULL) ? strlen(s) : 0;
fwrite(&len,sizeof(int),1,fpo);
if(len) fwrite(s,len,1,fpo);
}
void TrkWrite(UBYTE *t)
/*
Writes a track to fpo.
*/
{
UWORD len;
if(t==NULL) printf("NULL track");
len=TrkLen(t);
fwrite(&len,sizeof(int),1,fpo);
fwrite(t,len,1,fpo);
}
int main(int argc,char *argv[])
{
int t,v,w;
puts(mikbanner);
// Expand wildcards on commandline (only neccesary for MSDOS):
MyGlob(&argc,&argv,0);
/*
Register the loaders we want to use..
*/
ML_RegisterLoader(&m15load);
ML_RegisterLoader(&modload);
ML_RegisterLoader(&mtmload);
ML_RegisterLoader(&farload);
ML_RegisterLoader(&s69load);
ML_RegisterLoader(&s3mload);
ML_RegisterLoader(&stmload);
ML_RegisterLoader(&dsmload);
ML_RegisterLoader(&medload);
ML_RegisterLoader(&ultload);
ML_RegisterLoader(&uniload);
ML_RegisterLoader(&xmload);
if(argc==1 || argv[1][0]=='/'){
// display a usage message
puts("Usage: MIKCVT <fletch.mod> ... ");
puts("Converts your modules to .UNI modules\n");
exit(-1);
}
for(t=1; t<argc; t++){
UNIMOD *mf;
printf("In file : %s\n",argv[t]);
numsamples=0;
if((fpi=fopen(argv[t],"rb"))==NULL){
printf("MikCvt Error: Error opening input file\n");
break;
}
fnsplit(argv[t],drive,dir,name,ext);
fnmerge(path,NULL,NULL,name,".UNI");
printf("Out file: %s\n",path);
if((fpo=fopen(path,"wb"))==NULL){
printf("MikCvt Error: Error opening output file\n");
break;
}
mf=ML_LoadFP(fpi);
// didn't work -> exit with error
if(mf==NULL){
printf("MikCvt Error: %s\n",myerr);
fclose(fpi);
break;
}
printf( "Songname: %s\n"
"Modtype : %s\n",
mf->songname,
mf->modtype);
// Optimize the tracks
Optimize(mf);
// Write UNI header
fwrite("UN04",4,1,fpo);
fwrite(mf,sizeof(UNIHEADER),1,fpo);
StrWrite(mf->songname);
StrWrite(mf->modtype);
StrWrite(mf->comment);
// Write instruments
for(v=0;v<mf->numins;v++){
INSTRUMENT *i=&mf->instruments[v];
fwrite(i,sizeof(UNIINSTRUMENT),1,fpo);
StrWrite(i->insname);
for(w=0;w<i->numsmp;w++){
SAMPLE *s=&i->samples[w];
fwrite(s,sizeof(UNISAMPLE),1,fpo);
StrWrite(s->samplename);
}
}
// Write patterns
fwrite(mf->pattrows,sizeof(UWORD),mf->numpat,fpo);
fwrite(mf->patterns,sizeof(UWORD),mf->numpat*mf->numchn,fpo);
// Write tracks
for(v=0;v<mf->numtrk;v++){
TrkWrite(mf->tracks[v]);
}
printf("Writing samples.. ");
// Write sample-data
for(v=0;v<numsamples;v++){
fseek(fpi,samplepos[v],SEEK_SET);
CopyData(fpi,fpo,samplesize[v]);
}
puts("Done.");
// and clean up
fclose(fpo);
fclose(fpi);
ML_Free(mf);
}
return 0;
}