home *** CD-ROM | disk | FTP | other *** search
/ PC Loisirs 18 / cd.iso / sharewar / mikm202 / source / loaders / mtmload.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-18  |  4.8 KB  |  251 lines

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