home *** CD-ROM | disk | FTP | other *** search
/ The Games Machine 25 / GNOME_DEMO.iso / amiga / music / mikmod.lzx / mikmod / load_mtm.c < prev    next >
C/C++ Source or Header  |  2000-01-05  |  6KB  |  286 lines

  1. /*
  2.  
  3. Name:
  4. LOAD_MTM.C
  5.  
  6. Description:
  7. MTM module loader
  8.  
  9. Portability:
  10. All systems - all compilers (hopefully)
  11.  
  12. */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include "mikmod.h"
  18.  
  19. /**************************************************************************
  20. **************************************************************************/
  21.  
  22.  
  23. typedef struct MTMSAMPLE{
  24.     char  samplename[22];
  25.     ULONG length;
  26.     ULONG reppos;
  27.     ULONG repend;
  28.     UBYTE finetune;
  29.     UBYTE volume;
  30.     UBYTE attribute;
  31. } MTMSAMPLE;
  32.  
  33.  
  34.  
  35. typedef struct MTMHEADER{
  36.     UBYTE id[3];                            /* MTM file marker */
  37.     UBYTE version;                          /* upper major, lower nibble minor version number */
  38.     char  songname[20];                     /* ASCIIZ songname */
  39.     UWORD numtracks;                        /* number of tracks saved */
  40.     UBYTE lastpattern;                      /* last pattern number saved */
  41.     UBYTE lastorder;                        /* last order number to play (songlength-1) */
  42.     UWORD commentsize;                      /* length of comment field */
  43.     UBYTE numsamples;                       /* number of samples saved */
  44.     UBYTE attribute;                        /* attribute byte (unused) */
  45.     UBYTE beatspertrack;            /* */
  46.     UBYTE numchannels;                      /* number of channels used */
  47.     UBYTE panpos[32];                       /* voice pan positions */
  48. } MTMHEADER;
  49.  
  50.  
  51. typedef struct MTMNOTE{
  52.     UBYTE a,b,c;
  53. } MTMNOTE;
  54.  
  55.  
  56. /**************************************************************************
  57. **************************************************************************/
  58.  
  59.  
  60.  
  61. static MTMHEADER *mh;
  62. MTMNOTE *mtmtrk;
  63. UWORD pat[32];
  64.  
  65. char MTM_Version[]="MTM";
  66.  
  67.  
  68.  
  69. BOOL MTM_Test(void)
  70. {
  71.     char id[3];
  72.     if(!fread(id,3,1,modfp)) return 0;
  73.     if(!memcmp(id,"MTM",3)) return 1;
  74.     return 0;
  75. }
  76.  
  77.  
  78. BOOL MTM_Init(void)
  79. {
  80.     mtmtrk=NULL;
  81.     mh=NULL;
  82.  
  83.     if(!(mtmtrk=MyCalloc(64,sizeof(MTMNOTE)))) return 0;
  84.     if(!(mh=MyCalloc(1,sizeof(MTMHEADER)))) return 0;
  85.  
  86.     return 1;
  87. }
  88.  
  89.  
  90. void MTM_Cleanup(void)
  91. {
  92.     if(mtmtrk!=NULL) free(mtmtrk);
  93.     if(mh!=NULL) free(mh);
  94. }
  95.  
  96.  
  97.  
  98. UBYTE *MTM_Convert(void)
  99. {
  100.     int t;
  101.     UBYTE a,b,c,inst,note,eff,dat;
  102.  
  103.     UniReset();
  104.     for(t=0;t<64;t++){
  105.  
  106.         a=mtmtrk[t].a;
  107.         b=mtmtrk[t].b;
  108.         c=mtmtrk[t].c;
  109.  
  110.         inst=((a&0x3)<<4)|(b>>4);
  111.         note=a>>2;
  112.  
  113.         eff=b&0xf;
  114.         dat=c;
  115.  
  116.  
  117.         if(inst!=0){
  118.             UniInstrument(inst-1);
  119.         }
  120.  
  121.         if(note!=0){
  122.             UniNote(note+24);
  123.         }
  124.  
  125.         /* mtm bug bugfix: when the effect is volslide,
  126.            slide-up _always_ overrides slide-dn. */
  127.  
  128.         if(eff==0xa && dat&0xf0) dat&=0xf0;
  129.  
  130.         UniPTEffect(eff,dat);
  131.         UniNewline();
  132.     }
  133.     return UniDup();
  134. }
  135.  
  136.  
  137. BOOL MTM_Load(void)
  138. {
  139.     MTMSAMPLE s;
  140.     INSTRUMENT *d;
  141.     SAMPLE *q;
  142.  
  143.     int t,u;
  144.  
  145.     /* try to read module header */
  146.  
  147.     _mm_read_str(mh->id,3,modfp);
  148.     mh->version        =_mm_read_UBYTE(modfp);
  149.     _mm_read_str(mh->songname,20,modfp);
  150.     mh->numtracks    =_mm_read_I_UWORD(modfp);
  151.     mh->lastpattern    =_mm_read_UBYTE(modfp);
  152.     mh->lastorder    =_mm_read_UBYTE(modfp);
  153.     mh->commentsize    =_mm_read_I_UWORD(modfp);
  154.     mh->numsamples    =_mm_read_UBYTE(modfp);
  155.     mh->attribute    =_mm_read_UBYTE(modfp);
  156.     mh->beatspertrack=_mm_read_UBYTE(modfp);
  157.     mh->numchannels    =_mm_read_UBYTE(modfp);
  158.     _mm_read_UBYTES(mh->panpos,32,modfp);
  159.  
  160.     if(feof(modfp)){
  161.         myerr=ERROR_LOADING_HEADER;
  162.         return 0;
  163.     }
  164.  
  165.     /* set module variables */
  166.  
  167.     of.initspeed=6;
  168.     of.inittempo=125;
  169.     of.modtype=strdup(MTM_Version);
  170.     of.numchn=mh->numchannels;
  171.     of.numtrk=mh->numtracks+1;                              /* get number of channels */
  172.     of.songname=DupStr(mh->songname,20);    /* make a cstr of songname */
  173.     of.numpos=mh->lastorder+1;              /* copy the songlength */
  174.     of.numpat=mh->lastpattern+1;
  175.     for(t=0;t<32;t++) of.panning[t]=mh->panpos[t]<<4;
  176.  
  177.     of.numins=mh->numsamples;
  178.     if(!AllocInstruments()) return 0;
  179.  
  180.     d=of.instruments;
  181.  
  182.     for(t=0;t<of.numins;t++){
  183.  
  184.         d->numsmp=1;
  185.         if(!AllocSamples(d)) return 0;
  186.         q=d->samples;
  187.  
  188.         /* try to read sample info */
  189.  
  190.         _mm_read_str(s.samplename,22,modfp);
  191.         s.length    =_mm_read_I_ULONG(modfp);
  192.         s.reppos    =_mm_read_I_ULONG(modfp);
  193.         s.repend    =_mm_read_I_ULONG(modfp);
  194.         s.finetune    =_mm_read_UBYTE(modfp);
  195.         s.volume    =_mm_read_UBYTE(modfp);
  196.         s.attribute    =_mm_read_UBYTE(modfp);
  197.  
  198.         if(feof(modfp)){
  199.             myerr=ERROR_LOADING_SAMPLEINFO;
  200.             return 0;
  201.         }
  202.  
  203.         d->insname=DupStr(s.samplename,22);
  204.         q->seekpos=0;
  205.         q->c2spd=finetune[s.finetune];
  206.         q->length=s.length;
  207.         q->loopstart=s.reppos;
  208.         q->loopend=s.repend;
  209.         q->volume=s.volume;
  210.  
  211.         q->flags=0;
  212.  
  213.         if(s.repend-s.reppos>2) q->flags|=SF_LOOP;      /* <- 1.00 bugfix */
  214.  
  215.         if(s.attribute&1){
  216.  
  217.             /* If the sample is 16-bits, convert the length
  218.                and replen byte-values into sample-values */
  219.  
  220.             q->flags|=SF_16BITS;
  221.             q->length>>=1;
  222.             q->loopstart>>=1;
  223.             q->loopend>>=1;
  224.         }
  225.  
  226.         d++;
  227.     }
  228.  
  229.     _mm_read_UBYTES(of.positions,128,modfp);
  230.  
  231.     if(feof(modfp)){
  232.         myerr=ERROR_LOADING_HEADER;
  233.         return 0;
  234.     }
  235.  
  236.     if(!AllocTracks()) return 0;
  237.     if(!AllocPatterns()) return 0;
  238.  
  239.     of.tracks[0]=MTM_Convert();             /* track 0 is empty */
  240.  
  241.     for(t=1;t<of.numtrk;t++){
  242.         int s;
  243.  
  244.         for(s=0;s<64;s++){
  245.             mtmtrk[s].a=_mm_read_UBYTE(modfp);
  246.             mtmtrk[s].b=_mm_read_UBYTE(modfp);
  247.             mtmtrk[s].c=_mm_read_UBYTE(modfp);
  248.         }
  249.  
  250.         if(feof(modfp)){
  251.             myerr="Error loading track";
  252.             return 0;
  253.         }
  254.  
  255.         if(!(of.tracks[t]=MTM_Convert())) return 0;
  256.     }
  257.  
  258.     for(t=0;t<of.numpat;t++){
  259.  
  260.         _mm_read_I_UWORDS(pat,32,modfp);
  261.  
  262.         for(u=0;u<of.numchn;u++){
  263.             of.patterns[((long)t*of.numchn)+u]=pat[u];
  264.         }
  265.     }
  266.  
  267.     /* read comment field */
  268.  
  269.     if(!ReadComment(mh->commentsize)) return 0;
  270.  
  271.     return 1;
  272. }
  273.  
  274.  
  275.  
  276. LOADER load_mtm={
  277.     NULL,
  278.     "MTM",
  279.     "Portable MTM loader v0.1",
  280.     MTM_Init,
  281.     MTM_Test,
  282.     MTM_Load,
  283.     MTM_Cleanup
  284. };
  285.  
  286.