Metropoli BBS
VIEWER: mikcvt.c MODE: TEXT (ASCII)
#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;
}
[ RETURN TO DIRECTORY ]