/* megatracker.c 20140517 (c) Sylvain "Asle" Chipaux Atari Falcon tracker - mostly converted stuff from other trackers examples sent by Lotek Style ! :) --header-- 0 "MGT" string (megatracker) 3 1 byte - probably version .. seen 0x11 4 1 0xBD ? 5 "MCS" string (author) 8 2 number of voices 10 2 ? 12 2 patternlist size 14 2 number of pattern stored 16 2 nbr tracks stored 18 2 nbr sample defined ... ? 26 4 title pos 30 4 patlist pos 34 4 smp head address 38 4 pattern data track pointers 42 4 pos of tracks addresses 46 4 sample data */ #include #include #include int main( int ac, char **av ) { FILE *in,*out,*debug; unsigned char *in_data, *Whatever; long i,WholeSampleSize=0,nbrpatsaved,sizepatlist,nbrsmp, Where; long nbrtracksaved; long trackperpattern[128][32]; long trackaddresses[1024]; unsigned char trackptkformat[1024][64][4], ntkbyte; long smpdata[31][2]; long nbrvoice; unsigned char poss[60][2]; poss[0][0]=0x06, poss[0][1]=0xb0; poss[1][0]=0x06, poss[1][1]=0xb0; poss[2][0]=0x06, poss[2][1]=0xb0; poss[3][0]=0x06, poss[3][1]=0x50; poss[4][0]=0x05, poss[4][1]=0xf4; poss[5][0]=0x05, poss[5][1]=0x4c; /* 0 */ poss[6][0]=0x05, poss[6][1]=0x00; poss[7][0]=0x04, poss[7][1]=0xb8; poss[8][0]=0x04, poss[8][1]=0x74; poss[9][0]=0x03, poss[9][1]=0xf8; poss[10][0]=0x03, poss[10][1]=0xc0; poss[11][0]=0x03, poss[11][1]=0x8a; poss[12][0]=0x03, poss[12][1]=0x58; poss[13][0]=0x03, poss[13][1]=0x28; poss[14][0]=0x02, poss[14][1]=0xfa; poss[15][0]=0x02, poss[15][1]=0xd0; poss[16][0]=0x02, poss[16][1]=0xa6; poss[17][0]=0x02, poss[17][1]=0x80; /* 1 */ poss[18][0]=0x02, poss[18][1]=0x5c; poss[19][0]=0x02, poss[19][1]=0x3a; poss[20][0]=0x02, poss[20][1]=0x1a; poss[21][0]=0x01, poss[21][1]=0xfc; poss[22][0]=0x01, poss[22][1]=0xe0; poss[23][0]=0x01, poss[23][1]=0xc5; poss[24][0]=0x01, poss[24][1]=0xac; poss[25][0]=0x01, poss[25][1]=0x94; poss[26][0]=0x01, poss[26][1]=0x7d; poss[27][0]=0x01, poss[27][1]=0x68; poss[28][0]=0x01, poss[28][1]=0x53; poss[29][0]=0x01, poss[29][1]=0x40; /* 2 */ poss[30][0]=0x01, poss[30][1]=0x2e; poss[31][0]=0x01, poss[31][1]=0x1d; poss[32][0]=0x01, poss[32][1]=0x0d; poss[33][0]=0x00, poss[33][1]=0xfe; poss[34][0]=0x00, poss[34][1]=0xf0; poss[35][0]=0x00, poss[35][1]=0xe2; poss[36][0]=0x00, poss[36][1]=0xd6; poss[37][0]=0x00, poss[37][1]=0xca; poss[38][0]=0x00, poss[38][1]=0xbe; poss[39][0]=0x00, poss[39][1]=0xb4; poss[40][0]=0x00, poss[40][1]=0xaa; poss[41][0]=0x00, poss[41][1]=0xa0; /* 3 */ poss[42][0]=0x00, poss[42][1]=0x97; poss[43][0]=0x00, poss[43][1]=0x8f; poss[44][0]=0x00, poss[44][1]=0x87; poss[45][0]=0x00, poss[45][1]=0x7f; poss[46][0]=0x00, poss[46][1]=0x78; poss[47][0]=0x00, poss[47][1]=0x71; poss[48][0]=0x00, poss[48][1]=0x6b; poss[49][0]=0x00, poss[49][1]=0x65; poss[50][0]=0x00, poss[50][1]=0x5f; poss[51][0]=0x00, poss[51][1]=0x5a; poss[52][0]=0x00, poss[52][1]=0x55; poss[53][0]=0x00, poss[53][1]=0x50; poss[54][0]=0x00, poss[54][1]=0x4b; poss[55][0]=0x00, poss[55][1]=0x48; poss[56][0]=0x00, poss[56][1]=0x43; poss[57][0]=0x00, poss[57][1]=0x3f; poss[58][0]=0x00, poss[58][1]=0x3c; poss[59][0]=0x00, poss[59][1]=0x38; if (ac != 3) { printf ("%s \n",av[0]); exit (-1); } if (!(in = fopen(av[1],"r+b"))) { printf ("can't find '%s'\n", av[1]); exit (-1); } out = fopen ( av[2] , "w+b" ); debug = fopen ( "debug.txt" , "w+b" ); fseek ( in, 0, 2); i = ftell(in); fseek ( in,0,0); in_data = (unsigned char *) malloc (i); fread (in_data, 1, i, in); fclose (in); /* read header */ /* check version */ if (in_data[3] != 0x11) { printf ("unsupported Megatracker version (%x)\n",in_data[11]); fclose(out);fclose(debug); exit(-1); } /*nbr of subsongs*/ if (in_data[11] != 0x01) { printf ("more than one song (%x)\n",in_data[11]); fclose(out);fclose(debug); exit(-1); } nbrpatsaved = in_data[15]; nbrtracksaved = (in_data[16]*256) + in_data[17]; sizepatlist = in_data[13]; nbrsmp = in_data[19]; nbrvoice = in_data[9]; /*nbr of smp*/ if (nbrsmp > 0x1f) { printf ("unsupported number of smp (%d)\n",nbrsmp); fclose(out);fclose(debug); exit(-1); } /* read/write header */ Whatever = (unsigned char *) malloc (1084); memset (Whatever,0x00,1084); Where = (in_data[26]*256*256*256) + (in_data[27]*256*256) + (in_data[28]*256) + in_data[29]; for (i=0;i<20;i++) /* title */ Whatever[i] = in_data[Where+i]; Where += 39; ntkbyte = in_data[Where]; /* sample desc - one desc is 80 bytes long 0 32 title 32 4 file pos (from beginning) 36 4 size (real) 40 4 loop start (real) 44 4 loop size (real) 48 4 ? 52 4 ? 56 4 ? 60 2 vol * 16 62 2 ? 64 1 loop on ? 65 1 fine (same format as PTK) */ Where = (in_data[34]*256*256*256) + (in_data[35]*256*256) + (in_data[36]*256) + in_data[37]; for (i=0;i 0x03) j-=1;*/ } if ((in_data[Where] & 0x04) == 0x04) /*next byte is a note*/ { unsigned char c; cur +=1; c = (in_data[Where+cur]-12); fprintf (debug,"(note:%02x",c); if (((c/12)<2) || ((c/12)>6)) { printf ("out of Amiga range (%lx)(c:%x)(track:%ld)(row:%ld)\n",Where,c,i,j); fclose(out);fclose(debug); free(in_data);free(Whatever); exit(-2); } c -= 24; /* 36 */ trackptkformat[i][j][0] = poss[c][0]; trackptkformat[i][j][1] = poss[c][1]; fprintf (debug," %02x-%02x)",trackptkformat[i][j][0],trackptkformat[i][j][1]); } if ((in_data[Where] & 0x08) == 0x08) /*sample number*/ { cur +=1; trackptkformat[i][j][0] |= (in_data[Where+cur] & 0xf0); trackptkformat[i][j][2] = ((in_data[Where+cur]<<4) & 0xf0); fprintf (debug," (smp:%02x %02x-%02x)",in_data[Where+cur],trackptkformat[i][j][0],trackptkformat[i][j][2]); } if ((in_data[Where] & 0x10) == 0x10) /*vol column*/ { cur +=1; if (in_data[Where+cur] <= 0x50) { trackptkformat[i][j][2] |= 0x0c; trackptkformat[i][j][3] = (in_data[Where+cur]-0x10); } if ((in_data[Where+cur] < 0x70) && (in_data[Where+cur] >= 0x60)) /* slide down */ { trackptkformat[i][j][2] |= 0x0a; trackptkformat[i][j][3] = in_data[Where+cur] - 0x60; } if ((in_data[Where+cur] < 0x80) && (in_data[Where+cur] >= 0x70)) /* slide up */ { trackptkformat[i][j][2] |= 0x0a; trackptkformat[i][j][3] = (in_data[Where+cur]<<4); } if (in_data[Where+cur] >= 0x80) /* not supported */ { printf ("unsupported fx at %lx (%lx)\n",Where+cur,in_data[Where+cur]); trackptkformat[i][j][3] = (in_data[Where+cur]<<4); } fprintf (debug," (vol:%02x %02x-%02x)",in_data[Where+cur],trackptkformat[i][j][2],trackptkformat[i][j][3]); } if ((in_data[Where] & 0x20) == 0x20) /*fx */ { cur +=1; if (in_data[Where+cur] >= 0x10) /* ext. fx are remapped */ { trackptkformat[i][j][2] |= 0x0e; trackptkformat[i][j][3] = in_data[Where+cur]<<4; } else trackptkformat[i][j][2] |= in_data[Where+cur]; fprintf (debug," (fx:%02x %02x)",in_data[Where+cur],trackptkformat[i][j][2]); } if ((in_data[Where] & 0x40) == 0x40) /*fx arg 1 */ { cur +=1; /* seems when fx are 6 or 9, the arg is rolled ... */ if (((trackptkformat[i][j][2] & 0x0f) == 0x06) || ((trackptkformat[i][j][2] & 0x0f) == 0x09) || ((trackptkformat[i][j][2] & 0x0f) == 0x05)) { unsigned char d = (in_data[Where+cur]>>4); d |= (in_data[Where+cur]<<4); trackptkformat[i][j][3] |= d; } else trackptkformat[i][j][3] |= in_data[Where+cur]; fprintf (debug," (arg:%02x %02x)",in_data[Where+cur],trackptkformat[i][j][3]); } if ((in_data[Where] & 0x80) == 0x80) /*fx arg 2 ?!?!? - shouldn't be set when arg 1 exists */ { cur +=1; /* seems when fx are 6 or 9, the arg is rolled ... */ if (((trackptkformat[i][j][2] & 0x0f) == 0x06) || ((trackptkformat[i][j][2] & 0x0f) == 0x09) || ((trackptkformat[i][j][2] & 0x0f) == 0x05)) { unsigned char d = (in_data[Where+cur]>>4); d |= (in_data[Where+cur]<<4); trackptkformat[i][j][3] |= d; } else trackptkformat[i][j][3] = in_data[Where+cur]; fprintf (debug," (arg:%02x %02x)",in_data[Where+cur],trackptkformat[i][j][3]); } Where += (cur+1); fprintf (debug,"\n"); } } /* write the mess, now */ for (i=0; i< nbrpatsaved; i++) { long j,k; unsigned char *pat; pat = (unsigned char *)malloc (256*nbrvoice); memset (pat,0x00,256*nbrvoice); /*fprintf (debug,"pattern %ld (nbr voice:%ld)(size:%ld)\n",i,nbrvoice,256*nbrvoice);*/ for (j=0;j