pass -d2 for proper debug symbols
[dosdemo] / libs / mikmod / loaders / load_xm.c
1 /*      MikMod sound library
2         (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file
3         AUTHORS for complete list.
4
5         This library is free software; you can redistribute it and/or modify
6         it under the terms of the GNU Library General Public License as
7         published by the Free Software Foundation; either version 2 of
8         the License, or (at your option) any later version.
9
10         This program is distributed in the hope that it will be useful,
11         but WITHOUT ANY WARRANTY; without even the implied warranty of
12         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13         GNU Library General Public License for more details.
14
15         You should have received a copy of the GNU Library General Public
16         License along with this library; if not, write to the Free Software
17         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18         02111-1307, USA.
19 */
20
21 /*==============================================================================
22
23   $Id$
24
25   Fasttracker (XM) module loader
26
27 ==============================================================================*/
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36
37 #include <stdio.h>
38 #ifdef HAVE_MEMORY_H
39 #include <memory.h>
40 #endif
41 #include <string.h>
42
43 #include "mikmod_internals.h"
44
45 #ifdef SUNOS
46 extern int fprintf(FILE *, const char *, ...);
47 #endif
48
49 /*========== Module structure */
50
51 typedef struct XMHEADER {
52         CHAR  id[17];          /* ID text: 'Extended module: ' */
53         CHAR  songname[21];    /* Module name */
54         CHAR  trackername[20]; /* Tracker name */
55         UWORD version;         /* Version number */
56         ULONG headersize;      /* Header size */
57         UWORD songlength;      /* Song length (in patten order table) */
58         UWORD restart;         /* Restart position */
59         UWORD numchn;          /* Number of channels (2,4,6,8,10,...,32) */
60         UWORD numpat;          /* Number of patterns (max 256) */
61         UWORD numins;          /* Number of instruments (max 128) */
62         UWORD flags;
63         UWORD tempo;           /* Default tempo */
64         UWORD bpm;             /* Default BPM */
65         UBYTE orders[256];     /* Pattern order table  */
66 } XMHEADER;
67
68 typedef struct XMINSTHEADER {
69         ULONG size;     /* Instrument size */
70         CHAR  name[22]; /* Instrument name */
71         UBYTE type;     /* Instrument type (always 0) */
72         UWORD numsmp;   /* Number of samples in instrument */
73         ULONG ssize;
74 } XMINSTHEADER;
75
76 #define XMENVCNT (12*2)
77 #define XMNOTECNT (8*OCTAVE)
78 typedef struct XMPATCHHEADER {
79         UBYTE what[XMNOTECNT];  /*  Sample number for all notes */
80         UWORD volenv[XMENVCNT]; /*  Points for volume envelope */
81         UWORD panenv[XMENVCNT]; /*  Points for panning envelope */
82         UBYTE volpts;      /*  Number of volume points */
83         UBYTE panpts;      /*  Number of panning points */
84         UBYTE volsus;      /*  Volume sustain point */
85         UBYTE volbeg;      /*  Volume loop start point */
86         UBYTE volend;      /*  Volume loop end point */
87         UBYTE pansus;      /*  Panning sustain point */
88         UBYTE panbeg;      /*  Panning loop start point */
89         UBYTE panend;      /*  Panning loop end point */
90         UBYTE volflg;      /*  Volume type: bit 0: On; 1: Sustain; 2: Loop */
91         UBYTE panflg;      /*  Panning type: bit 0: On; 1: Sustain; 2: Loop */
92         UBYTE vibflg;      /*  Vibrato type */
93         UBYTE vibsweep;    /*  Vibrato sweep */
94         UBYTE vibdepth;    /*  Vibrato depth */
95         UBYTE vibrate;     /*  Vibrato rate */
96         UWORD volfade;     /*  Volume fadeout */
97 } XMPATCHHEADER;
98
99 typedef struct XMWAVHEADER {
100         ULONG length;         /* Sample length */
101         ULONG loopstart;      /* Sample loop start */
102         ULONG looplength;     /* Sample loop length */
103         UBYTE volume;         /* Volume  */
104         SBYTE finetune;       /* Finetune (signed byte -128..+127) */
105         UBYTE type;           /* Loop type */
106         UBYTE panning;        /* Panning (0-255) */
107         SBYTE relnote;        /* Relative note number (signed byte) */
108         UBYTE reserved;
109         CHAR  samplename[22]; /* Sample name */
110         UBYTE vibtype;        /* Vibrato type */
111         UBYTE vibsweep;       /* Vibrato sweep */
112         UBYTE vibdepth;       /* Vibrato depth */
113         UBYTE vibrate;        /* Vibrato rate */
114 } XMWAVHEADER;
115
116 typedef struct XMPATHEADER {
117         ULONG size;     /* Pattern header length  */
118         UBYTE packing;  /* Packing type (always 0) */
119         UWORD numrows;  /* Number of rows in pattern (1..256) */
120         SWORD packsize; /* Packed patterndata size */
121 } XMPATHEADER;
122
123 typedef struct XMNOTE {
124         UBYTE note,ins,vol,eff,dat;
125 } XMNOTE;
126
127 /*========== Loader variables */
128
129 static  XMNOTE *xmpat=NULL;
130 static  XMHEADER *mh=NULL;
131
132 /* increment unit for sample array reallocation */
133 #define XM_SMPINCR 64
134 static  ULONG *nextwav=NULL;
135 static  XMWAVHEADER *wh=NULL,*s=NULL;
136
137 /*========== Loader code */
138
139 static BOOL XM_Test(void)
140 {
141         UBYTE id[38];
142
143         if(!_mm_read_UBYTES(id,38,modreader)) return 0;
144         if(memcmp(id,"Extended Module: ",17)) return 0;
145         if(id[37]==0x1a) return 1;
146         return 0;
147 }
148
149 static BOOL XM_Init(void)
150 {
151         if(!(mh=(XMHEADER *)MikMod_malloc(sizeof(XMHEADER)))) return 0;
152         return 1;
153 }
154
155 static void XM_Cleanup(void)
156 {
157         MikMod_free(mh);
158         mh=NULL;
159 }
160
161 static int XM_ReadNote(XMNOTE* n)
162 {
163         UBYTE cmp,result=1;
164
165         memset(n,0,sizeof(XMNOTE));
166         cmp=_mm_read_UBYTE(modreader);
167
168         if(cmp&0x80) {
169                 if(cmp&1)  { result++;n->note = _mm_read_UBYTE(modreader); }
170                 if(cmp&2)  { result++;n->ins  = _mm_read_UBYTE(modreader); }
171                 if(cmp&4)  { result++;n->vol  = _mm_read_UBYTE(modreader); }
172                 if(cmp&8)  { result++;n->eff  = _mm_read_UBYTE(modreader); }
173                 if(cmp&16) { result++;n->dat  = _mm_read_UBYTE(modreader); }
174         } else {
175                 n->note = cmp;
176                 n->ins  = _mm_read_UBYTE(modreader);
177                 n->vol  = _mm_read_UBYTE(modreader);
178                 n->eff  = _mm_read_UBYTE(modreader);
179                 n->dat  = _mm_read_UBYTE(modreader);
180                 result += 4;
181         }
182         return result;
183 }
184
185 static UBYTE* XM_Convert(XMNOTE* xmtrack,UWORD rows)
186 {
187         int t;
188         UBYTE note,ins,vol,eff,dat;
189
190         UniReset();
191         for(t=0;t<rows;t++) {
192                 note = xmtrack->note;
193                 ins  = xmtrack->ins;
194                 vol  = xmtrack->vol;
195                 eff  = xmtrack->eff;
196                 dat  = xmtrack->dat;
197
198                 if(note) {
199                         if(note>XMNOTECNT)
200                                 UniEffect(UNI_KEYFADE,0);
201                         else
202                                 UniNote(note-1);
203                 }
204                 if(ins) UniInstrument(ins-1);
205
206                 switch(vol>>4) {
207                         case 0x6: /* volslide down */
208                                 if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol&0xf);
209                                 break;
210                         case 0x7: /* volslide up */
211                                 if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol<<4);
212                                 break;
213
214                                 /* volume-row fine volume slide is compatible with protracker
215                                    EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as
216                                    opposed to 'take the last sliding value'. */
217                         case 0x8: /* finevol down */
218                                 UniPTEffect(0xe,0xb0|(vol&0xf));
219                                 break;
220                         case 0x9: /* finevol up */
221                                 UniPTEffect(0xe,0xa0|(vol&0xf));
222                                 break;
223                         case 0xa: /* set vibrato speed */
224                                 UniEffect(UNI_XMEFFECT4,vol<<4);
225                                 break;
226                         case 0xb: /* vibrato */
227                                 UniEffect(UNI_XMEFFECT4,vol&0xf);
228                                 break;
229                         case 0xc: /* set panning */
230                                 UniPTEffect(0x8,vol<<4);
231                                 break;
232                         case 0xd: /* panning slide left (only slide when data not zero) */
233                                 if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol&0xf);
234                                 break;
235                         case 0xe: /* panning slide right (only slide when data not zero) */
236                                 if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol<<4);
237                                 break;
238                         case 0xf: /* tone porta */
239                                 UniPTEffect(0x3,vol<<4);
240                                 break;
241                         default:
242                                 if((vol>=0x10)&&(vol<=0x50))
243                                         UniPTEffect(0xc,vol-0x10);
244                 }
245
246                 switch(eff) {
247                         case 0x4:
248                                 UniEffect(UNI_XMEFFECT4,dat);
249                                 break;
250                         case 0x6:
251                                 UniEffect(UNI_XMEFFECT6,dat);
252                                 break;
253                         case 0xa:
254                                 UniEffect(UNI_XMEFFECTA,dat);
255                                 break;
256                         case 0xe: /* Extended effects */
257                                 switch(dat>>4) {
258                                         case 0x1: /* XM fine porta up */
259                                                 UniEffect(UNI_XMEFFECTE1,dat&0xf);
260                                                 break;
261                                         case 0x2: /* XM fine porta down */
262                                                 UniEffect(UNI_XMEFFECTE2,dat&0xf);
263                                                 break;
264                                         case 0xa: /* XM fine volume up */
265                                                 UniEffect(UNI_XMEFFECTEA,dat&0xf);
266                                                 break;
267                                         case 0xb: /* XM fine volume down */
268                                                 UniEffect(UNI_XMEFFECTEB,dat&0xf);
269                                                 break;
270                                         default:
271                                                 UniPTEffect(eff,dat);
272                                 }
273                                 break;
274                         case 'G'-55: /* G - set global volume */
275                                 UniEffect(UNI_XMEFFECTG,dat>64?128:dat<<1);
276                                 break;
277                         case 'H'-55: /* H - global volume slide */
278                                 UniEffect(UNI_XMEFFECTH,dat);
279                                 break;
280                         case 'K'-55: /* K - keyOff and KeyFade */
281                                 UniEffect(UNI_KEYFADE,dat);
282                                 break;
283                         case 'L'-55: /* L - set envelope position */
284                                 UniEffect(UNI_XMEFFECTL,dat);
285                                 break;
286                         case 'P'-55: /* P - panning slide */
287                                 UniEffect(UNI_XMEFFECTP,dat);
288                                 break;
289                         case 'R'-55: /* R - multi retrig note */
290                                 UniEffect(UNI_S3MEFFECTQ,dat);
291                                 break;
292                         case 'T'-55: /* T - Tremor */
293                                 UniEffect(UNI_S3MEFFECTI,dat);
294                                 break;
295                         case 'X'-55:
296                                 switch(dat>>4) {
297                                         case 1: /* X1 - Extra Fine Porta up */
298                                                 UniEffect(UNI_XMEFFECTX1,dat&0xf);
299                                                 break;
300                                         case 2: /* X2 - Extra Fine Porta down */
301                                                 UniEffect(UNI_XMEFFECTX2,dat&0xf);
302                                                 break;
303                                 }
304                                 break;
305                         default:
306                                 if(eff<=0xf) {
307                                         /* the pattern jump destination is written in decimal,
308                                            but it seems some poor tracker software writes them
309                                            in hexadecimal... (sigh) */
310                                         if (eff==0xd)
311                                                 /* don't change anything if we're sure it's in hexa */
312                                                 if ((((dat&0xf0)>>4)<=9)&&((dat&0xf)<=9))
313                                                         /* otherwise, convert from dec to hex */
314                                                         dat=(((dat&0xf0)>>4)*10)+(dat&0xf);
315                                         UniPTEffect(eff,dat);
316                                 }
317                                 break;
318                 }
319                 UniNewline();
320                 xmtrack++;
321         }
322         return UniDup();
323 }
324
325 static BOOL LoadPatterns(BOOL dummypat)
326 {
327         int t,u,v,numtrk;
328
329         if(!AllocTracks()) return 0;
330         if(!AllocPatterns()) return 0;
331
332         numtrk=0;
333         for(t=0;t<mh->numpat;t++) {
334                 XMPATHEADER ph;
335
336                 ph.size     =_mm_read_I_ULONG(modreader);
337                 if (ph.size<(mh->version==0x0102?8:9)) {
338                         _mm_errno=MMERR_LOADING_PATTERN;
339                         return 0;
340                 }
341                 ph.packing  =_mm_read_UBYTE(modreader);
342                 if(ph.packing) {
343                         _mm_errno=MMERR_LOADING_PATTERN;
344                         return 0;
345                 }
346                 if(mh->version==0x0102)
347                         ph.numrows  =_mm_read_UBYTE(modreader)+1;
348                 else
349                         ph.numrows  =_mm_read_I_UWORD(modreader);
350                 ph.packsize =_mm_read_I_UWORD(modreader);
351
352                 ph.size-=(mh->version==0x0102?8:9);
353                 if(ph.size)
354                         _mm_fseek(modreader,ph.size,SEEK_CUR);
355
356                 of.pattrows[t]=ph.numrows;
357
358                 if(ph.numrows) {
359                         if(!(xmpat=(XMNOTE*)MikMod_calloc(ph.numrows*of.numchn,sizeof(XMNOTE))))
360                                 return 0;
361
362                         /* when packsize is 0, don't try to load a pattern.. it's empty. */
363                         if(ph.packsize)
364                                 for(u=0;u<ph.numrows;u++)
365                                         for(v=0;v<of.numchn;v++) {
366                                                 if(!ph.packsize) break;
367
368                                                 ph.packsize-=XM_ReadNote(&xmpat[(v*ph.numrows)+u]);
369                                                 if(ph.packsize<0) {
370                                                         MikMod_free(xmpat);xmpat=NULL;
371                                                         _mm_errno=MMERR_LOADING_PATTERN;
372                                                         return 0;
373                                                 }
374                                         }
375
376                         if(ph.packsize) {
377                                 _mm_fseek(modreader,ph.packsize,SEEK_CUR);
378                         }
379
380                         if(_mm_eof(modreader)) {
381                                 MikMod_free(xmpat);xmpat=NULL;
382                                 _mm_errno=MMERR_LOADING_PATTERN;
383                                 return 0;
384                         }
385
386                         for(v=0;v<of.numchn;v++)
387                                 of.tracks[numtrk++]=XM_Convert(&xmpat[v*ph.numrows],ph.numrows);
388
389                         MikMod_free(xmpat);xmpat=NULL;
390                 } else {
391                         for(v=0;v<of.numchn;v++)
392                                 of.tracks[numtrk++]=XM_Convert(NULL,ph.numrows);
393                 }
394         }
395
396         if(dummypat) {
397                 of.pattrows[t]=64;
398                 if(!(xmpat=(XMNOTE*)MikMod_calloc(64*of.numchn,sizeof(XMNOTE)))) return 0;
399                 for(v=0;v<of.numchn;v++)
400                         of.tracks[numtrk++]=XM_Convert(&xmpat[v*64],64);
401                 MikMod_free(xmpat);xmpat=NULL;
402         }
403
404         return 1;
405 }
406
407 static void FixEnvelope(ENVPT *cur, int pts)
408 {
409                 int u, old, tmp;
410                 ENVPT *prev;
411
412                 /* Some broken XM editing program will only save the low byte
413                    of the position value. Try to compensate by adding the
414                    missing high byte. */
415
416                 prev = cur++;
417                 old = prev->pos;
418
419                 for (u = 1; u < pts; u++, prev++, cur++) {
420                         if (cur->pos < prev->pos) {
421                                 if (cur->pos < 0x100) {
422                                         if (cur->pos > old)     /* same hex century */
423                                                         tmp = cur->pos + (prev->pos - old);
424                                         else
425                                                         tmp = cur->pos | ((prev->pos + 0x100) & 0xff00);
426                                         old = cur->pos;
427                                         cur->pos = tmp;
428 #ifdef MIKMOD_DEBUG
429                                         fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d -> %d\n",
430                                             u, pts, prev->pos, old, cur->pos);
431 #endif
432                                 } else {
433 #ifdef MIKMOD_DEBUG
434                                         /* different brokenness style... fix unknown */
435                                         fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d\n",
436                                             u, pts, old, cur->pos);
437 #endif
438                                         old = cur->pos;
439                                 }
440                         } else
441                                 old = cur->pos;
442                 }
443 }
444
445 static BOOL LoadInstruments(void)
446 {
447         int t,u, ck;
448         INSTRUMENT *d;
449         ULONG next=0;
450         UWORD wavcnt=0;
451
452         if(!AllocInstruments()) return 0;
453         d=of.instruments;
454         for(t=0;t<of.numins;t++,d++) {
455                 XMINSTHEADER ih;
456                 long headend;
457
458                 memset(d->samplenumber,0xff,INSTNOTES*sizeof(UWORD));
459
460                 /* read instrument header */
461                 headend     = _mm_ftell(modreader);
462                 ih.size     = _mm_read_I_ULONG(modreader);
463                 headend    += ih.size;
464                 ck = _mm_ftell(modreader);
465                 _mm_fseek(modreader,0,SEEK_END);
466                 if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) {
467                         _mm_fseek(modreader,ck,SEEK_SET);
468                         break;
469                 }
470                 _mm_fseek(modreader,ck,SEEK_SET);
471                 _mm_read_string(ih.name, 22, modreader);
472                 ih.type     = _mm_read_UBYTE(modreader);
473                 ih.numsmp   = _mm_read_I_UWORD(modreader);
474
475                 d->insname  = DupStr(ih.name,22,1);
476
477                 if((SWORD)ih.size>29) {
478                         ih.ssize    = _mm_read_I_ULONG(modreader);
479                         if(((SWORD)ih.numsmp>0)&&(ih.numsmp<=XMNOTECNT)) {
480                                 XMPATCHHEADER pth;
481                                 int p;
482
483                                 _mm_read_UBYTES (pth.what,XMNOTECNT,modreader);
484                                 _mm_read_I_UWORDS (pth.volenv, XMENVCNT, modreader);
485                                 _mm_read_I_UWORDS (pth.panenv, XMENVCNT, modreader);
486                                 pth.volpts      =  _mm_read_UBYTE(modreader);
487                                 pth.panpts      =  _mm_read_UBYTE(modreader);
488                                 pth.volsus      =  _mm_read_UBYTE(modreader);
489                                 pth.volbeg      =  _mm_read_UBYTE(modreader);
490                                 pth.volend      =  _mm_read_UBYTE(modreader);
491                                 pth.pansus      =  _mm_read_UBYTE(modreader);
492                                 pth.panbeg      =  _mm_read_UBYTE(modreader);
493                                 pth.panend      =  _mm_read_UBYTE(modreader);
494                                 pth.volflg      =  _mm_read_UBYTE(modreader);
495                                 pth.panflg      =  _mm_read_UBYTE(modreader);
496                                 pth.vibflg      =  _mm_read_UBYTE(modreader);
497                                 pth.vibsweep    =  _mm_read_UBYTE(modreader);
498                                 pth.vibdepth    =  _mm_read_UBYTE(modreader);
499                                 pth.vibrate     =  _mm_read_UBYTE(modreader);
500                                 pth.volfade     =  _mm_read_I_UWORD(modreader);
501
502                                 /* read the remainder of the header
503                                    (2 bytes for 1.03, 22 for 1.04) */
504                                 if (headend>=_mm_ftell(modreader)) {
505                                         for(u=headend-_mm_ftell(modreader);u;u--) {
506                                                 _mm_skip_BYTE(modreader);
507                                         }
508                                 }
509
510                                 /* we can't trust the envelope point count here, as some
511                                    modules have incorrect values (K_OSPACE.XM reports 32 volume
512                                    points, for example). */
513                                 if(pth.volpts>XMENVCNT/2) pth.volpts=XMENVCNT/2;
514                                 if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2;
515
516                                 if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) {
517                                         MikMod_free(nextwav);nextwav=NULL;
518                                         MikMod_free(wh);wh=NULL;
519                                         _mm_errno = MMERR_LOADING_SAMPLEINFO;
520                                         return 0;
521                                 }
522
523                                 for(u=0;u<XMNOTECNT;u++)
524                                         d->samplenumber[u]=pth.what[u]+of.numsmp;
525                                 d->volfade = pth.volfade;
526
527 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
528 #define XM_ProcessEnvelope(name)                                                                                \
529                                 for (u = 0; u < (XMENVCNT >> 1); u++) {                                 \
530                                         d-> name##env[u].pos = pth. name##env[u << 1];          \
531                                         d-> name##env[u].val = pth. name##env[(u << 1)+ 1];     \
532                                 }                                                                                                               \
533                                 if (pth. name##flg&1) d-> name##flg|=EF_ON;                             \
534                                 if (pth. name##flg&2) d-> name##flg|=EF_SUSTAIN;                \
535                                 if (pth. name##flg&4) d-> name##flg|=EF_LOOP;                   \
536                                 d-> name##susbeg=d-> name##susend=pth. name##sus;               \
537                                 d-> name##beg=pth. name##beg;                                                   \
538                                 d-> name##end=pth. name##end;                                                   \
539                                 d-> name##pts=pth. name##pts;                                                   \
540                                                                                                                                                 \
541                                 /* scale envelope */                                                                    \
542                                 for (p=0;p<XMENVCNT/2;p++)                                                              \
543                                         d-> name##env[p].val<<=2;                                                       \
544                                                                                                                                                 \
545                                 if ((d-> name##flg&EF_ON)&&(d-> name##pts<2))                   \
546                                         d-> name##flg&=~EF_ON
547 #else
548 #define XM_ProcessEnvelope(name)                                                                                        \
549                                 for (u = 0; u < (XMENVCNT >> 1); u++) {                                         \
550                                         d-> name/**/env[u].pos = pth. name/**/env[u << 1];              \
551                                         d-> name/**/env[u].val = pth. name/**/env[(u << 1)+ 1]; \
552                                 }                                                                                                                       \
553                                 if (pth. name/**/flg&1) d-> name/**/flg|=EF_ON;                         \
554                                 if (pth. name/**/flg&2) d-> name/**/flg|=EF_SUSTAIN;            \
555                                 if (pth. name/**/flg&4) d-> name/**/flg|=EF_LOOP;                       \
556                                 d-> name/**/susbeg=d-> name/**/susend=                                          \
557                                                       pth. name/**/sus;                                         \
558                                 d-> name/**/beg=pth. name/**/beg;                                                       \
559                                 d-> name/**/end=pth. name/**/end;                                                       \
560                                 d-> name/**/pts=pth. name/**/pts;                                                       \
561                                                                                                                                                         \
562                                 /* scale envelope */                                                                            \
563                                 for (p=0;p<XMENVCNT/2;p++)                                                                      \
564                                         d-> name/**/env[p].val<<=2;                                                             \
565                                                                                                                                                         \
566                                 if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2))                       \
567                                         d-> name/**/flg&=~EF_ON
568 #endif
569
570                                 XM_ProcessEnvelope(vol);
571                                 XM_ProcessEnvelope(pan);
572 #undef XM_ProcessEnvelope
573
574                                 if (d->volflg & EF_ON)
575                                         FixEnvelope(d->volenv, d->volpts);
576                                 if (d->panflg & EF_ON)
577                                         FixEnvelope(d->panenv, d->panpts);
578
579                                 /* Samples are stored outside the instrument struct now, so we
580                                    have to load them all into a temp area, count the of.numsmp
581                                    along the way and then do an AllocSamples() and move
582                                    everything over */
583                                 if(mh->version>0x0103) next = 0;
584                                 for(u=0;u<ih.numsmp;u++,s++) {
585                                         /* Allocate more room for sample information if necessary */
586                                         if(of.numsmp+u==wavcnt) {
587                                                 wavcnt+=XM_SMPINCR;
588                                                 if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
589                                                         MikMod_free(wh);wh=NULL;
590                                                         _mm_errno = MMERR_OUT_OF_MEMORY;
591                                                         return 0;
592                                                 }
593                                                 if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
594                                                         MikMod_free(nextwav);nextwav=NULL;
595                                                         _mm_errno = MMERR_OUT_OF_MEMORY;
596                                                         return 0;
597                                                 }
598                                                 s=wh+(wavcnt-XM_SMPINCR);
599                                         }
600
601                                         s->length       =_mm_read_I_ULONG (modreader);
602                                         s->loopstart    =_mm_read_I_ULONG (modreader);
603                                         s->looplength   =_mm_read_I_ULONG (modreader);
604                                         s->volume       =_mm_read_UBYTE (modreader);
605                                         s->finetune     =_mm_read_SBYTE (modreader);
606                                         s->type         =_mm_read_UBYTE (modreader);
607                                         s->panning      =_mm_read_UBYTE (modreader);
608                                         s->relnote      =_mm_read_SBYTE (modreader);
609                                         s->vibtype      = pth.vibflg;
610                                         s->vibsweep     = pth.vibsweep;
611                                         s->vibdepth     = pth.vibdepth*4;
612                                         s->vibrate      = pth.vibrate;
613                                         s->reserved     =_mm_read_UBYTE (modreader);
614                                         _mm_read_string(s->samplename, 22, modreader);
615
616                                         nextwav[of.numsmp+u]=next;
617                                         next+=s->length;
618
619                                         /* last instrument is at the end of file in version 0x0104 */
620                                         if(_mm_eof(modreader) && (mh->version<0x0104 || t<of.numins-1)) {
621                                                 MikMod_free(nextwav);MikMod_free(wh);
622                                                 nextwav=NULL;wh=NULL;
623                                                 _mm_errno = MMERR_LOADING_SAMPLEINFO;
624                                                 return 0;
625                                         }
626                                 }
627
628                                 if(mh->version>0x0103) {
629                                         for(u=0;u<ih.numsmp;u++)
630                                                 nextwav[of.numsmp++]+=_mm_ftell(modreader);
631                                         _mm_fseek(modreader,next,SEEK_CUR);
632                                 } else
633                                         of.numsmp+=ih.numsmp;
634                         } else {
635                                 /* read the remainder of the header */
636                                 ck = _mm_ftell(modreader);
637                                 _mm_fseek(modreader,0,SEEK_END);
638                                 if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) {
639                                         _mm_fseek(modreader,ck,SEEK_SET);
640                                         break;
641                                 }
642                                 _mm_fseek(modreader,ck,SEEK_SET);
643                                 for(u=headend-_mm_ftell(modreader);u;u--) {
644                                         _mm_skip_BYTE(modreader);
645                                 }
646
647                                 /* last instrument is at the end of file in version 0x0104 */
648                                 if(_mm_eof(modreader) && (mh->version<0x0104 || t<of.numins-1)) {
649                                         MikMod_free(nextwav);MikMod_free(wh);
650                                         nextwav=NULL;wh=NULL;
651                                         _mm_errno = MMERR_LOADING_SAMPLEINFO;
652                                         return 0;
653                                 }
654                         }
655                 }
656         }
657
658         /* sanity check */
659         if(!of.numsmp) {
660                 MikMod_free(nextwav);nextwav=NULL;
661                 MikMod_free(wh);wh=NULL;
662                 _mm_errno = MMERR_LOADING_SAMPLEINFO;
663                 return 0;
664         }
665
666         return 1;
667 }
668
669 static BOOL XM_Load(BOOL curious)
670 {
671         INSTRUMENT *d;
672         SAMPLE *q;
673         int t,u;
674         BOOL dummypat=0;
675         char tracker[21],modtype[60];
676
677         /* try to read module header */
678         _mm_read_string(mh->id,17,modreader);
679         _mm_read_string(mh->songname,21,modreader);
680         _mm_read_string(mh->trackername,20,modreader);
681         mh->version     =_mm_read_I_UWORD(modreader);
682         if((mh->version<0x102)||(mh->version>0x104)) {
683                 _mm_errno=MMERR_NOT_A_MODULE;
684                 return 0;
685         }
686         mh->headersize  =_mm_read_I_ULONG(modreader);
687         mh->songlength  =_mm_read_I_UWORD(modreader);
688         mh->restart     =_mm_read_I_UWORD(modreader);
689         mh->numchn      =_mm_read_I_UWORD(modreader);
690         mh->numpat      =_mm_read_I_UWORD(modreader);
691         mh->numins      =_mm_read_I_UWORD(modreader);
692         mh->flags       =_mm_read_I_UWORD(modreader);
693         mh->tempo       =_mm_read_I_UWORD(modreader);
694         mh->bpm         =_mm_read_I_UWORD(modreader);
695         if(!mh->bpm || mh->songlength > 256) {
696                 _mm_errno=MMERR_NOT_A_MODULE;
697                 return 0;
698         }
699 /*      _mm_read_UBYTES(mh->orders,256,modreader);*/
700 /*      _mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);*/
701         _mm_read_UBYTES(mh->orders,mh->songlength,modreader);
702         if(_mm_fseek(modreader, mh->headersize+60, SEEK_SET) ||
703            _mm_eof(modreader)) {
704                 _mm_errno = MMERR_LOADING_HEADER;
705                 return 0;
706         }
707
708         /* set module variables */
709         of.initspeed = mh->tempo;
710         of.inittempo = mh->bpm;
711         strncpy(tracker,mh->trackername,20);tracker[20]=0;
712         for(t=20;(t>=0)&&(tracker[t]<=' ');t--) tracker[t]=0;
713
714         /* some modules have the tracker name empty */
715         if (!tracker[0])
716                 strcpy(tracker,"Unknown tracker");
717
718 #ifdef HAVE_SNPRINTF
719         snprintf(modtype,60,"%s (XM format %d.%02d)",
720                             tracker,mh->version>>8,mh->version&0xff);
721 #else
722         sprintf(modtype,"%s (XM format %d.%02d)",
723                         tracker,mh->version>>8,mh->version&0xff);
724 #endif
725         of.modtype   = MikMod_strdup(modtype);
726         of.numchn    = mh->numchn;
727         of.numpat    = mh->numpat;
728         of.numtrk    = (UWORD)of.numpat*of.numchn;   /* get number of channels */
729         of.songname  = DupStr(mh->songname,20,1);
730         of.numpos    = mh->songlength;               /* copy the songlength */
731         of.reppos    = mh->restart<mh->songlength?mh->restart:0;
732         of.numins    = mh->numins;
733         of.flags    |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS |
734                                    UF_PANNING;
735         if(mh->flags&1) of.flags |= UF_LINEAR;
736         of.bpmlimit  = 32;
737
738         memset(of.chanvol,64,of.numchn);             /* store channel volumes */
739
740         if(!AllocPositions(of.numpos+1)) return 0;
741         for(t=0;t<of.numpos;t++)
742                 of.positions[t]=mh->orders[t];
743
744         /* We have to check for any pattern numbers in the order list greater than
745            the number of patterns total. If one or more is found, we set it equal to
746            the pattern total and make a dummy pattern to workaround the problem */
747         for(t=0;t<of.numpos;t++) {
748                 if(of.positions[t]>=of.numpat) {
749                         of.positions[t]=of.numpat;
750                         dummypat=1;
751                 }
752         }
753         if(dummypat) {
754                 of.numpat++;of.numtrk+=of.numchn;
755         }
756
757         if(mh->version<0x0104) {
758                 if(!LoadInstruments()) return 0;
759                 if(!LoadPatterns(dummypat)) return 0;
760                 for(t=0;t<of.numsmp;t++)
761                         nextwav[t]+=_mm_ftell(modreader);
762         } else {
763                 if(!LoadPatterns(dummypat)) return 0;
764                 if(!LoadInstruments()) return 0;
765         }
766
767         if(!AllocSamples()) {
768                 MikMod_free(nextwav);MikMod_free(wh);
769                 nextwav=NULL;wh=NULL;
770                 return 0;
771         }
772         q = of.samples;
773         s = wh;
774         for(u=0;u<of.numsmp;u++,q++,s++) {
775                 q->samplename   = DupStr(s->samplename,22,1);
776                 q->length       = s->length;
777                 q->loopstart    = s->loopstart;
778                 q->loopend      = s->loopstart+s->looplength;
779                 q->volume       = s->volume;
780                 q->speed        = s->finetune+128;
781                 q->panning      = s->panning;
782                 q->seekpos      = nextwav[u];
783                 q->vibtype      = s->vibtype;
784                 q->vibsweep     = s->vibsweep;
785                 q->vibdepth     = s->vibdepth;
786                 q->vibrate      = s->vibrate;
787
788                 if(s->type & 0x10) {
789                         q->length    >>= 1;
790                         q->loopstart >>= 1;
791                         q->loopend   >>= 1;
792                 }
793
794                 q->flags|=SF_OWNPAN|SF_DELTA|SF_SIGNED;
795                 if(s->type&0x3) q->flags|=SF_LOOP;
796                 if(s->type&0x2) q->flags|=SF_BIDI;
797                 if(s->type&0x10) q->flags|=SF_16BITS;
798         }
799
800         d=of.instruments;
801         s=wh;
802         for(u=0;u<of.numins;u++,d++)
803                 for(t=0;t<XMNOTECNT;t++) {
804                         if (d->samplenumber[t]>=of.numsmp)
805                                 d->samplenote[t]=255;
806                         else {
807                                 int note=t+s[d->samplenumber[t]].relnote;
808                                 d->samplenote[t]=(note<0)?0:note;
809                         }
810                 }
811
812         MikMod_free(wh);MikMod_free(nextwav);
813         wh=NULL;nextwav=NULL;
814         return 1;
815 }
816
817 static CHAR *XM_LoadTitle(void)
818 {
819         CHAR str[21];
820
821         _mm_fseek(modreader,17,SEEK_SET);
822         if(!_mm_read_UBYTES(str, 21, modreader)) return NULL;
823
824         return(DupStr(str,21,1));
825 }
826
827 /*========== Loader information */
828
829 MIKMODAPI MLOADER load_xm={
830         NULL,
831         "XM",
832         "XM (FastTracker 2)",
833         XM_Init,
834         XM_Test,
835         XM_Load,
836         XM_Cleanup,
837         XM_LoadTitle
838 };
839
840 /* ex:set ts=4: */