1 /* MikMod sound library
2 (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file
3 AUTHORS for complete list.
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.
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.
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
21 /*==============================================================================
25 Fasttracker (XM) module loader
27 ==============================================================================*/
43 #include "mikmod_internals.h"
46 extern int fprintf(FILE *, const char *, ...);
49 /*========== Module structure */
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) */
63 UWORD tempo; /* Default tempo */
64 UWORD bpm; /* Default BPM */
65 UBYTE orders[256]; /* Pattern order table */
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 */
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 */
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) */
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 */
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 */
123 typedef struct XMNOTE {
124 UBYTE note,ins,vol,eff,dat;
127 /*========== Loader variables */
129 static XMNOTE *xmpat=NULL;
130 static XMHEADER *mh=NULL;
132 /* increment unit for sample array reallocation */
133 #define XM_SMPINCR 64
134 static ULONG *nextwav=NULL;
135 static XMWAVHEADER *wh=NULL,*s=NULL;
137 /*========== Loader code */
139 static BOOL XM_Test(void)
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;
149 static BOOL XM_Init(void)
151 if(!(mh=(XMHEADER *)MikMod_malloc(sizeof(XMHEADER)))) return 0;
155 static void XM_Cleanup(void)
161 static int XM_ReadNote(XMNOTE* n)
165 memset(n,0,sizeof(XMNOTE));
166 cmp=_mm_read_UBYTE(modreader);
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); }
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);
185 static UBYTE* XM_Convert(XMNOTE* xmtrack,UWORD rows)
188 UBYTE note,ins,vol,eff,dat;
191 for(t=0;t<rows;t++) {
192 note = xmtrack->note;
200 UniEffect(UNI_KEYFADE,0);
204 if(ins) UniInstrument(ins-1);
207 case 0x6: /* volslide down */
208 if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol&0xf);
210 case 0x7: /* volslide up */
211 if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol<<4);
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));
220 case 0x9: /* finevol up */
221 UniPTEffect(0xe,0xa0|(vol&0xf));
223 case 0xa: /* set vibrato speed */
224 UniEffect(UNI_XMEFFECT4,vol<<4);
226 case 0xb: /* vibrato */
227 UniEffect(UNI_XMEFFECT4,vol&0xf);
229 case 0xc: /* set panning */
230 UniPTEffect(0x8,vol<<4);
232 case 0xd: /* panning slide left (only slide when data not zero) */
233 if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol&0xf);
235 case 0xe: /* panning slide right (only slide when data not zero) */
236 if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol<<4);
238 case 0xf: /* tone porta */
239 UniPTEffect(0x3,vol<<4);
242 if((vol>=0x10)&&(vol<=0x50))
243 UniPTEffect(0xc,vol-0x10);
248 UniEffect(UNI_XMEFFECT4,dat);
251 UniEffect(UNI_XMEFFECT6,dat);
254 UniEffect(UNI_XMEFFECTA,dat);
256 case 0xe: /* Extended effects */
258 case 0x1: /* XM fine porta up */
259 UniEffect(UNI_XMEFFECTE1,dat&0xf);
261 case 0x2: /* XM fine porta down */
262 UniEffect(UNI_XMEFFECTE2,dat&0xf);
264 case 0xa: /* XM fine volume up */
265 UniEffect(UNI_XMEFFECTEA,dat&0xf);
267 case 0xb: /* XM fine volume down */
268 UniEffect(UNI_XMEFFECTEB,dat&0xf);
271 UniPTEffect(eff,dat);
274 case 'G'-55: /* G - set global volume */
275 UniEffect(UNI_XMEFFECTG,dat>64?128:dat<<1);
277 case 'H'-55: /* H - global volume slide */
278 UniEffect(UNI_XMEFFECTH,dat);
280 case 'K'-55: /* K - keyOff and KeyFade */
281 UniEffect(UNI_KEYFADE,dat);
283 case 'L'-55: /* L - set envelope position */
284 UniEffect(UNI_XMEFFECTL,dat);
286 case 'P'-55: /* P - panning slide */
287 UniEffect(UNI_XMEFFECTP,dat);
289 case 'R'-55: /* R - multi retrig note */
290 UniEffect(UNI_S3MEFFECTQ,dat);
292 case 'T'-55: /* T - Tremor */
293 UniEffect(UNI_S3MEFFECTI,dat);
297 case 1: /* X1 - Extra Fine Porta up */
298 UniEffect(UNI_XMEFFECTX1,dat&0xf);
300 case 2: /* X2 - Extra Fine Porta down */
301 UniEffect(UNI_XMEFFECTX2,dat&0xf);
307 /* the pattern jump destination is written in decimal,
308 but it seems some poor tracker software writes them
309 in hexadecimal... (sigh) */
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);
325 static BOOL LoadPatterns(BOOL dummypat)
329 if(!AllocTracks()) return 0;
330 if(!AllocPatterns()) return 0;
333 for(t=0;t<mh->numpat;t++) {
336 ph.size =_mm_read_I_ULONG(modreader);
337 if (ph.size<(mh->version==0x0102?8:9)) {
338 _mm_errno=MMERR_LOADING_PATTERN;
341 ph.packing =_mm_read_UBYTE(modreader);
343 _mm_errno=MMERR_LOADING_PATTERN;
346 if(mh->version==0x0102)
347 ph.numrows =_mm_read_UBYTE(modreader)+1;
349 ph.numrows =_mm_read_I_UWORD(modreader);
350 ph.packsize =_mm_read_I_UWORD(modreader);
352 ph.size-=(mh->version==0x0102?8:9);
354 _mm_fseek(modreader,ph.size,SEEK_CUR);
356 of.pattrows[t]=ph.numrows;
359 if(!(xmpat=(XMNOTE*)MikMod_calloc(ph.numrows*of.numchn,sizeof(XMNOTE))))
362 /* when packsize is 0, don't try to load a pattern.. it's empty. */
364 for(u=0;u<ph.numrows;u++)
365 for(v=0;v<of.numchn;v++) {
366 if(!ph.packsize) break;
368 ph.packsize-=XM_ReadNote(&xmpat[(v*ph.numrows)+u]);
370 MikMod_free(xmpat);xmpat=NULL;
371 _mm_errno=MMERR_LOADING_PATTERN;
377 _mm_fseek(modreader,ph.packsize,SEEK_CUR);
380 if(_mm_eof(modreader)) {
381 MikMod_free(xmpat);xmpat=NULL;
382 _mm_errno=MMERR_LOADING_PATTERN;
386 for(v=0;v<of.numchn;v++)
387 of.tracks[numtrk++]=XM_Convert(&xmpat[v*ph.numrows],ph.numrows);
389 MikMod_free(xmpat);xmpat=NULL;
391 for(v=0;v<of.numchn;v++)
392 of.tracks[numtrk++]=XM_Convert(NULL,ph.numrows);
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;
407 static void FixEnvelope(ENVPT *cur, int pts)
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. */
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);
425 tmp = cur->pos | ((prev->pos + 0x100) & 0xff00);
429 fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d -> %d\n",
430 u, pts, prev->pos, old, cur->pos);
434 /* different brokenness style... fix unknown */
435 fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d\n",
436 u, pts, old, cur->pos);
445 static BOOL LoadInstruments(void)
452 if(!AllocInstruments()) return 0;
454 for(t=0;t<of.numins;t++,d++) {
458 memset(d->samplenumber,0xff,INSTNOTES*sizeof(UWORD));
460 /* read instrument header */
461 headend = _mm_ftell(modreader);
462 ih.size = _mm_read_I_ULONG(modreader);
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);
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);
475 d->insname = DupStr(ih.name,22,1);
477 if((SWORD)ih.size>29) {
478 ih.ssize = _mm_read_I_ULONG(modreader);
479 if(((SWORD)ih.numsmp>0)&&(ih.numsmp<=XMNOTECNT)) {
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);
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);
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;
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;
523 for(u=0;u<XMNOTECNT;u++)
524 d->samplenumber[u]=pth.what[u]+of.numsmp;
525 d->volfade = pth.volfade;
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]; \
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; \
541 /* scale envelope */ \
542 for (p=0;p<XMENVCNT/2;p++) \
543 d-> name##env[p].val<<=2; \
545 if ((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \
546 d-> name##flg&=~EF_ON
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]; \
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= \
558 d-> name/**/beg=pth. name/**/beg; \
559 d-> name/**/end=pth. name/**/end; \
560 d-> name/**/pts=pth. name/**/pts; \
562 /* scale envelope */ \
563 for (p=0;p<XMENVCNT/2;p++) \
564 d-> name/**/env[p].val<<=2; \
566 if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
567 d-> name/**/flg&=~EF_ON
570 XM_ProcessEnvelope(vol);
571 XM_ProcessEnvelope(pan);
572 #undef XM_ProcessEnvelope
574 if (d->volflg & EF_ON)
575 FixEnvelope(d->volenv, d->volpts);
576 if (d->panflg & EF_ON)
577 FixEnvelope(d->panenv, d->panpts);
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
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) {
588 if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
589 MikMod_free(wh);wh=NULL;
590 _mm_errno = MMERR_OUT_OF_MEMORY;
593 if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
594 MikMod_free(nextwav);nextwav=NULL;
595 _mm_errno = MMERR_OUT_OF_MEMORY;
598 s=wh+(wavcnt-XM_SMPINCR);
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);
616 nextwav[of.numsmp+u]=next;
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;
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);
633 of.numsmp+=ih.numsmp;
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);
642 _mm_fseek(modreader,ck,SEEK_SET);
643 for(u=headend-_mm_ftell(modreader);u;u--) {
644 _mm_skip_BYTE(modreader);
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;
660 MikMod_free(nextwav);nextwav=NULL;
661 MikMod_free(wh);wh=NULL;
662 _mm_errno = MMERR_LOADING_SAMPLEINFO;
669 static BOOL XM_Load(BOOL curious)
675 char tracker[21],modtype[60];
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;
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;
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;
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;
714 /* some modules have the tracker name empty */
716 strcpy(tracker,"Unknown tracker");
719 snprintf(modtype,60,"%s (XM format %d.%02d)",
720 tracker,mh->version>>8,mh->version&0xff);
722 sprintf(modtype,"%s (XM format %d.%02d)",
723 tracker,mh->version>>8,mh->version&0xff);
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 |
735 if(mh->flags&1) of.flags |= UF_LINEAR;
738 memset(of.chanvol,64,of.numchn); /* store channel volumes */
740 if(!AllocPositions(of.numpos+1)) return 0;
741 for(t=0;t<of.numpos;t++)
742 of.positions[t]=mh->orders[t];
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;
754 of.numpat++;of.numtrk+=of.numchn;
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);
763 if(!LoadPatterns(dummypat)) return 0;
764 if(!LoadInstruments()) return 0;
767 if(!AllocSamples()) {
768 MikMod_free(nextwav);MikMod_free(wh);
769 nextwav=NULL;wh=NULL;
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;
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;
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;
807 int note=t+s[d->samplenumber[t]].relnote;
808 d->samplenote[t]=(note<0)?0:note;
812 MikMod_free(wh);MikMod_free(nextwav);
813 wh=NULL;nextwav=NULL;
817 static CHAR *XM_LoadTitle(void)
821 _mm_fseek(modreader,17,SEEK_SET);
822 if(!_mm_read_UBYTES(str, 21, modreader)) return NULL;
824 return(DupStr(str,21,1));
827 /*========== Loader information */
829 MIKMODAPI MLOADER load_xm={
832 "XM (FastTracker 2)",