/* quick hack 670 -> C67 convertor by Daredevil/Renaissance (3/22/97) */

#include <stdio.h>

main (int argc, char *argv[])
{
    int dinsempty[4] = {0,0,0,0xFFFFFF00};
    char patempty[3] = {0x40,0x40,0x60};
    char *buf,*p;
    int filesize,c,o,x,t;
    FILE *fp,*fpo;

    if (argc < 3){
        printf ("\nusage: 670toc67 <670 filename> <output filename>\n");
        exit(1);
    }

    fp = fopen (argv[1],"rb");
    if (fp == NULL) {printf ("Error opening input file!\n"); exit(1);}
    filesize = filelength(fileno(fp));

    fpo = fopen (argv[2],"wb");

    buf = (char *) malloc (filesize);
    if (buf == NULL) {printf ("Unable to allocate %d bytes!\n",filesize); exit(1);}
    fread (buf,filesize,1,fp);

    fwrite (buf,1,1,fpo);                       // Tempo
    fwrite (buf+5,1,1,fpo);                     // Order loop

//--------------------------------------------------------------------------
    for (c=0; c<(13*32); c++)
        fputc (0,fpo);                          // Digital ins. names

    o = *(char *)(buf+1);                       // get # of orders
    o += *(char *)(buf+2)*4;                    // add # of patterns*4
    o += 10;

    c = *(char *)(buf + 3);                     // # of digital ins.
    p = buf+o;
    for (x=0; x<c; x++)
    {
        fwrite (p,16,1,fpo);                    // write digital ins.
        p += 16;
    }
    for (x=0; x<(32-c); x++)
        fwrite (dinsempty,16,1,fpo);            // write empty digital ins.

//--------------------------------------------------------------------------
    for (c=0; c<(13*32); c++)
        fputc (0,fpo);                          // FM ins. names

    o = *(char *)(buf+1);                       // get # of orders
    o += *(char *)(buf+2)*4;                    // add # of patterns*4
    o += *(char *)(buf+3)*16;                   // add # of digital ins.
    o += 10;

    c = *(char *)(buf + 4);                     // # of FM ins.
    p = buf+o;
    for (x=0; x<c; x++)
    {
        fwrite (p,11,1,fpo);                    // write FM ins.
        p += 11;
    }
    for (x=0; x<(32-c); x++)
        fwrite (dinsempty,11,1,fpo);           // write empty FM ins.

//--------------------------------------------------------------------------
    c = *(char *)(buf+1);
    p = buf+10;
    fwrite (p,c,1,fpo);                        // write order list
    for (x=0; x<(256-c); x++) fputc (0xff,fpo);

//--------------------------------------------------------------------------
    o = *(char *)(buf+1);                       // get # of orders
    o += 10;

    p = buf+o;
    c = *(char *)(buf+2);
    fwrite (p,c*4,1,fpo);                       // write used pattern offsets

    o = 10 + *(char *)(buf+1) + (*(char *)(buf+2)*4) + (*(char *)(buf+3)*16) + (*(char *)(buf+4)*11);
    o += *(int *)(p+(c*4)-4);
    o = *(int *)(buf+6) - o;

    o += *(int *)(p+(c*4)-4);

    for (x=0; x<(128-c); x++){
        fwrite (&o,4,1,fpo);                    // write empty pattern offsets
        o+=3;
    }

//--------------------------------------------------------------------------
    o = *(char *)(buf+1);                       // get # of orders
    o += 10;

    p = buf+o;
    c = *(char *)(buf+2);

    o = 10 + *(char *)(buf+1) + (*(char *)(buf+2)*4) + (*(char *)(buf+3)*16) + (*(char *)(buf+4)*11);
    o += *(int *)(p+(c*4)-4);
    o = *(int *)(buf+6) - o;

    for (x=0; x<c; x++){
        if (x == c-1) t = o;
        else t = *(int *)(p+4) - *(int *)(p);
        fwrite (&t, 4, 1, fpo);                 // write pattern lengths
        p+=4;
    }

    t = 3;
    for (x=0; x<(128-c); x++) fwrite (&t,4,1,fpo);

//--------------------------------------------------------------------------
    o = 10 + *(char *)(buf+1) + (*(char *)(buf+2)*4) + (*(char *)(buf+3)*16) + (*(char *)(buf+4)*11);

    c = *(int *)(buf+6) - o;
    p = buf+o;

    fwrite (p,c,1,fpo);

    c = *(char *)(buf+2);
    for (x=0; x<(128-c); x++)
        fwrite (patempty,3,1,fpo);

//--------------------------------------------------------------------------
    o = *(int *)(buf+6);
    p = buf+o;
    c = filesize-o;
    fwrite (p,c,1,fpo);

    fclose (fp);
    fclose (fpo);
}

/*
; 670 muzik format:
; 0       1db     tempo for whole muzik
; 1       1db     number of orders
; 2       1db     number of patterns
; 3       1db     number of digital instruments
; 4       1db     number of FM instruments
; 5       1db     order loop
; 6       1dd     offset (from beginning of block) of digital instruments
; 10      ?db     order list
;         ?dd     pattern offset (from beginning of patterns) list
;         ?4dd    digital instrument data
;         ?11db   FM instrument data
;         ?db     patterns{
;           high 3 bits are command:
;           000vvvvv - note, byte[1]=iooonnnn, byte[2]=iiiivvvv
;           001vvvvv - volume, byte[1]=0000vvvv
;           010????? - delay, byte[1]=dddddddd
;           011????? - break pattern
*/

/*
 C67 muzik format
0       byte    mztempo
1       byte    mzloop
2       13*32   dinsnames
418     16*32   dinsbase
930     13*32   fminsnames
1346    11*32   fminsbase
1698    256     ordbase
1954    4*128   patoffbase
2466    4*128   patlenbase
2978    ?       pattern data
?       ?       digital instrument data
*/
