Metropoli BBS
VIEWER: mod2tbm.c MODE: TEXT (ASCII)
/*USE MEDIUM MODEL!!!*/
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
FILE *mod,*tbrmod;
void makenames(char *,char *);
/* Amiga note values */
int notes[36]={856,808,762,720,678,640,604,570,538,508,480,453,
			   428,404,381,360,339,320,302,285,269,254,240,226,
			   214,202,190,180,170,160,151,143,135,127,120,113};
char sambuf[64000]; /* Temporary buffer for samples */
void main(int argc,char *argv[])
{
	int n; /*loop variable*/
	unsigned int b2,b,m,seg=0;
	unsigned char by,by2,by3,by4,re1,re2,re3,re4;
	char segpad[32];
	unsigned long pos;
	unsigned char buffer[1024],hi_pattern;
	char songpos[128];
	unsigned int sam_lenght[32],rep_beg[32],rep_len[32];
	unsigned int sam_reallen[32];
	unsigned char sam_vol[32],sam_finetune[32],songlenght;
	char tbmname[256],modname[256];
	printf("ProTracker 1.1B module to Black Rain module 1.0 compiler\n");
	printf("Version 1.1 (C) 1993 Erwin / TBR\n");
	if(argc!=2){
		printf("Usage: mod2tbm infile[.mod]\n");
		exit(1);
	}
	strcpy(modname,argv[1]);
	makenames(modname,tbmname);
	mod=fopen(modname,"rb");
	if(mod==NULL){
		printf("Can't open %s!\n",modname);
		exit(1);
	}
	tbrmod=fopen(tbmname,"wb");
	if(tbrmod==NULL){
		printf("Can't open %s!\n",tbmname);
		exit(1);
	}
	fread(buffer,1,20,mod);
	printf("Processing song %s\n",buffer);
	printf("Song includes following samples:\n");
	for(n=0;n<31;n++){
		fread(buffer,1,22,mod);
		buffer[22]=0;
		if(strlen(buffer)) printf("%d: %s\n",n+1,buffer);
		m=fgetc(mod);
		b=fgetc(mod);
		sam_lenght[n]=((m<<8)+b)*2; /* do amiga byte conversion */
		m=fgetc(mod);
		sam_finetune[n]=m; /* fine tune & vol are bytes - no converion needed*/
		m=fgetc(mod);
		sam_vol[n]=m;
		m=fgetc(mod);
		b=fgetc(mod);
		rep_beg[n]=((m<<8)+b)*2;
		m=fgetc(mod);
		b=fgetc(mod);
		rep_len[n]=((m<<8)+b)*2;
	}
	songlenght=getc(mod);
	m=fgetc(mod); /* this byte isn't used */
	fread(songpos,1,128,mod); /* read song positions (128 of them)*/
	printf("\n");
    hi_pattern=0; /* highes pattern #, used by our gusplayer - that was written
                in 2 days an pretty much sucks - to figure out how many
                there are to be loaded*/
    for(n=0;n<songlenght;n++) /* find highest pattern number */
		if(songpos[n]>hi_pattern) hi_pattern=songpos[n];
    fread(buffer,1,4,mod); /* these 4 bytes contain letters 'M.K.' or something
                            else */
    pos=(448+1024*hi_pattern+1024);/* position in tbm module*/
	printf("Converting sample data...\n");
	for(n=0;n<31;n++){
        segpad[n]=pos%16; /*since the samples are 32-bit aligned we sometimes
                need to add a few bytes in frot if them to make it start
                at a page boundary */
		if(segpad[n]){
			segpad[n]=16-segpad[n];
			pos+=segpad[n];
		}
		seg=pos>>4;
        putw(seg,tbrmod);       /* samples segment address in tbm mod */
        if(rep_len[n]>2) sam_reallen[n]=rep_beg[n]+rep_len[n];
			else sam_reallen[n]=sam_lenght[n];
        if(sam_reallen[n]<=1) putw(0,tbrmod);  /*the lenght of the sample */
            else putw(sam_reallen[n]-1,tbrmod);
        putc(sam_vol[n],tbrmod);                /*volume*/
        putc(sam_finetune[n],tbrmod);           /*finetune*/
        putw(sam_reallen[n]-rep_beg[n],tbrmod);/*repeat begin*/
        if(rep_len[n]<=2) putw(0,tbrmod);       /* if zero don't loop sample*/
            else putw(1,tbrmod);            /*if 1 loop it */
        pos+=sam_reallen[n];        /*add position*/
	}
    putc(songlenght,tbrmod);    /* write song lenght */
    putc(hi_pattern,tbrmod);    /* write highest pattern */
	printf("Converting patterns...\n");
    fwrite(songpos,1,128,tbrmod); /*write song positions */
    fwrite(songpos,1,8,tbrmod);  /*these bytes are here to make the
                                patterns start at a page boundary */
	for(n=0;n<=hi_pattern;n++)
		for(m=0;m<256;m++){
			by=fgetc(mod);  /* read channel's data (see fformat.txt for more*/
			by2=fgetc(mod); /* info)*/
			by3=fgetc(mod);
			by4=fgetc(mod);
			re1=by&0x0f;
			b=(re1<<8)+by2;
			if(b){
				for(re1=0;re1<36;re1++) /*get note number:C-1=1, C#1 = 2 etc.*/
					if(notes[re1]==b){
						re1++;
						break;
					}
			}
			fputc(re1,tbrmod);
            re2=(by&0xf0)+(by3>>4); /*# of sample*/
			fputc(re2,tbrmod);
			re3=by3&0x0f;
            fputc(re3,tbrmod);  /*effect cmd*/
            fputc(by4,tbrmod);  /*cmd info*/
		}
	for(n=0;n<16;n++) buffer[n]=0;//0x80;
	printf("Converting samples...\n");
	for(n=0;n<31;n++){
        if(segpad[n]) fwrite(buffer,1,segpad[n],tbrmod); /*make sample start
                                at a page boundary*/
        fread(sambuf,1,sam_lenght[n],mod); /*read sample*/
        for(m=sam_reallen[n]-1;m!=0xffff;m--) /*write it BACKWARDS and convert*/
            fputc((sambuf[m]^0x80),tbrmod);/*it into 8-bit unsigned format*/
	}
    printf("Done.\n");  /*we are done now*/
    fclose(mod);    /*close files*/
	fclose(tbrmod);
}
void makenames(char *infile,char *outfile)
{
	char *inbak;
	inbak=infile;
	while(*inbak) inbak++;
	while(*inbak!=':'&&*inbak!='\\'&&inbak>=infile){
		inbak--;
	}
	inbak++;
	while(*inbak!=0&&*inbak!='.') *outfile=*inbak,outfile++,inbak++;
	*outfile=0;
	strcat(outfile,".tbm");
	if(*inbak==0) strcat(inbak,".mod");
	return;
}

[ RETURN TO DIRECTORY ]