10 All systems - all compilers (hopefully)
19 /**************************************************************************
20 **************************************************************************/
23 typedef struct MTMSAMPLE{
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 */
51 typedef struct MTMNOTE{
56 /**************************************************************************
57 **************************************************************************/
65 char MTM_Version[]="MTM";
72 if(!fread(id,3,1,modfp)) return 0;
73 if(!memcmp(id,"MTM",3)) return 1;
83 if(!(mtmtrk=(MTMNOTE *)MyCalloc(64,sizeof(MTMNOTE)))) return 0;
84 if(!(mh=(MTMHEADER *)MyCalloc(1,sizeof(MTMHEADER)))) return 0;
90 void MTM_Cleanup(void)
92 if(mtmtrk!=NULL) free(mtmtrk);
93 if(mh!=NULL) free(mh);
98 UBYTE *MTM_Convert(void)
101 UBYTE a,b,c,inst,note,eff,dat;
110 inst=((a&0x3)<<4)|(b>>4);
118 UniInstrument(inst-1);
125 /* mtm bug bugfix: when the effect is volslide,
126 slide-up _always_ overrides slide-dn. */
128 if(eff==0xa && dat&0xf0) dat&=0xf0;
130 UniPTEffect(eff,dat);
145 /* try to read module header */
147 _mm_read_UBYTES(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);
161 myerr=ERROR_LOADING_HEADER;
165 /* set module variables */
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;
177 of.numins=mh->numsamples;
178 if(!AllocInstruments()) return 0;
182 for(t=0;t<of.numins;t++){
185 if(!AllocSamples(d)) return 0;
188 /* try to read sample info */
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);
199 myerr=ERROR_LOADING_SAMPLEINFO;
203 d->insname=DupStr(s.samplename,22);
205 q->c2spd=finetune[s.finetune];
207 q->loopstart=s.reppos;
213 if(s.repend-s.reppos>2) q->flags|=SF_LOOP; /* <- 1.00 bugfix */
217 /* If the sample is 16-bits, convert the length
218 and replen byte-values into sample-values */
229 _mm_read_UBYTES(of.positions,128,modfp);
232 myerr=ERROR_LOADING_HEADER;
236 if(!AllocTracks()) return 0;
237 if(!AllocPatterns()) return 0;
239 of.tracks[0]=MTM_Convert(); /* track 0 is empty */
241 for(t=1;t<of.numtrk;t++){
245 mtmtrk[s].a=_mm_read_UBYTE(modfp);
246 mtmtrk[s].b=_mm_read_UBYTE(modfp);
247 mtmtrk[s].c=_mm_read_UBYTE(modfp);
251 myerr="Error loading track";
255 if(!(of.tracks[t]=MTM_Convert())) return 0;
258 for(t=0;t<of.numpat;t++){
260 _mm_read_I_UWORDS(pat,32,modfp);
262 for(u=0;u<of.numchn;u++){
263 of.patterns[((long)t*of.numchn)+u]=pat[u];
267 /* read comment field */
269 if(!ReadComment(mh->commentsize)) return 0;
279 "Portable MTM loader v0.1",