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 /*==============================================================================
23 $Id: load_xm.c,v 1.5 2008/02/29 18:49:03 denis111 Exp $
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 MikMod_reallocation */
133 #define XM_SMPINCR 64
134 static ULONG
*nextwav
=NULL
;
135 static XMWAVHEADER
*wh
=NULL
,*s
=NULL
;
137 /*========== Loader code */
139 static int 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 int XM_Init(void)
151 if(!(mh
=(XMHEADER
*)MikMod_malloc(sizeof(XMHEADER
)))) return 0;
155 static void XM_Cleanup(void)
160 static int XM_ReadNote(XMNOTE
* n
)
164 memset(n
,0,sizeof(XMNOTE
));
165 cmp
=_mm_read_UBYTE(modreader
);
168 if(cmp
&1) { result
++;n
->note
= _mm_read_UBYTE(modreader
); }
169 if(cmp
&2) { result
++;n
->ins
= _mm_read_UBYTE(modreader
); }
170 if(cmp
&4) { result
++;n
->vol
= _mm_read_UBYTE(modreader
); }
171 if(cmp
&8) { result
++;n
->eff
= _mm_read_UBYTE(modreader
); }
172 if(cmp
&16) { result
++;n
->dat
= _mm_read_UBYTE(modreader
); }
175 n
->ins
= _mm_read_UBYTE(modreader
);
176 n
->vol
= _mm_read_UBYTE(modreader
);
177 n
->eff
= _mm_read_UBYTE(modreader
);
178 n
->dat
= _mm_read_UBYTE(modreader
);
184 static UBYTE
* XM_Convert(XMNOTE
* xmtrack
,UWORD rows
)
187 UBYTE note
,ins
,vol
,eff
,dat
;
190 for(t
=0;t
<rows
;t
++) {
191 note
= xmtrack
->note
;
199 UniEffect(UNI_KEYFADE
,0);
203 if(ins
) UniInstrument(ins
-1);
206 case 0x6: /* volslide down */
207 if(vol
&0xf) UniEffect(UNI_XMEFFECTA
,vol
&0xf);
209 case 0x7: /* volslide up */
210 if(vol
&0xf) UniEffect(UNI_XMEFFECTA
,vol
<<4);
213 /* volume-row fine volume slide is compatible with protracker
214 EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as
215 opposed to 'take the last sliding value'. */
216 case 0x8: /* finevol down */
217 UniPTEffect(0xe,0xb0|(vol
&0xf));
219 case 0x9: /* finevol up */
220 UniPTEffect(0xe,0xa0|(vol
&0xf));
222 case 0xa: /* set vibrato speed */
223 UniEffect(UNI_XMEFFECT4
,vol
<<4);
225 case 0xb: /* vibrato */
226 UniEffect(UNI_XMEFFECT4
,vol
&0xf);
228 case 0xc: /* set panning */
229 UniPTEffect(0x8,vol
<<4);
231 case 0xd: /* panning slide left (only slide when data not zero) */
232 if(vol
&0xf) UniEffect(UNI_XMEFFECTP
,vol
&0xf);
234 case 0xe: /* panning slide right (only slide when data not zero) */
235 if(vol
&0xf) UniEffect(UNI_XMEFFECTP
,vol
<<4);
237 case 0xf: /* tone porta */
238 UniPTEffect(0x3,vol
<<4);
241 if((vol
>=0x10)&&(vol
<=0x50))
242 UniPTEffect(0xc,vol
-0x10);
247 UniEffect(UNI_XMEFFECT4
,dat
);
250 UniEffect(UNI_XMEFFECT6
,dat
);
253 UniEffect(UNI_XMEFFECTA
,dat
);
255 case 0xe: /* Extended effects */
257 case 0x1: /* XM fine porta up */
258 UniEffect(UNI_XMEFFECTE1
,dat
&0xf);
260 case 0x2: /* XM fine porta down */
261 UniEffect(UNI_XMEFFECTE2
,dat
&0xf);
263 case 0xa: /* XM fine volume up */
264 UniEffect(UNI_XMEFFECTEA
,dat
&0xf);
266 case 0xb: /* XM fine volume down */
267 UniEffect(UNI_XMEFFECTEB
,dat
&0xf);
270 UniPTEffect(eff
,dat
);
273 case 'G'-55: /* G - set global volume */
274 UniEffect(UNI_XMEFFECTG
,dat
>64?128:dat
<<1);
276 case 'H'-55: /* H - global volume slide */
277 UniEffect(UNI_XMEFFECTH
,dat
);
279 case 'K'-55: /* K - keyOff and KeyFade */
280 UniEffect(UNI_KEYFADE
,dat
);
282 case 'L'-55: /* L - set envelope position */
283 UniEffect(UNI_XMEFFECTL
,dat
);
285 case 'P'-55: /* P - panning slide */
286 UniEffect(UNI_XMEFFECTP
,dat
);
288 case 'R'-55: /* R - multi retrig note */
289 UniEffect(UNI_S3MEFFECTQ
,dat
);
291 case 'T'-55: /* T - Tremor */
292 UniEffect(UNI_S3MEFFECTI
,dat
);
296 case 1: /* X1 - Extra Fine Porta up */
297 UniEffect(UNI_XMEFFECTX1
,dat
&0xf);
299 case 2: /* X2 - Extra Fine Porta down */
300 UniEffect(UNI_XMEFFECTX2
,dat
&0xf);
306 /* the pattern jump destination is written in decimal,
307 but it seems some poor tracker software writes them
308 in hexadecimal... (sigh) */
310 /* don't change anything if we're sure it's in hexa */
311 if ((((dat
&0xf0)>>4)<=9)&&((dat
&0xf)<=9))
312 /* otherwise, convert from dec to hex */
313 dat
=(((dat
&0xf0)>>4)*10)+(dat
&0xf);
314 UniPTEffect(eff
,dat
);
324 static int LoadPatterns(int dummypat
)
328 if(!AllocTracks()) return 0;
329 if(!AllocPatterns()) return 0;
332 for(t
=0;t
<mh
->numpat
;t
++) {
335 ph
.size
=_mm_read_I_ULONG(modreader
);
336 if (ph
.size
<(mh
->version
==0x0102?8:9)) {
337 _mm_errno
=MMERR_LOADING_PATTERN
;
340 ph
.packing
=_mm_read_UBYTE(modreader
);
342 _mm_errno
=MMERR_LOADING_PATTERN
;
345 if(mh
->version
==0x0102)
346 ph
.numrows
=_mm_read_UBYTE(modreader
)+1;
348 ph
.numrows
=_mm_read_I_UWORD(modreader
);
349 ph
.packsize
=_mm_read_I_UWORD(modreader
);
351 ph
.size
-=(mh
->version
==0x0102?8:9);
353 _mm_fseek(modreader
,ph
.size
,SEEK_CUR
);
355 of
.pattrows
[t
]=ph
.numrows
;
358 if(!(xmpat
=(XMNOTE
*)MikMod_calloc(ph
.numrows
*of
.numchn
,sizeof(XMNOTE
))))
361 /* when packsize is 0, don't try to load a pattern.. it's empty. */
363 for(u
=0;u
<ph
.numrows
;u
++)
364 for(v
=0;v
<of
.numchn
;v
++) {
365 if(!ph
.packsize
) break;
367 ph
.packsize
-=XM_ReadNote(&xmpat
[(v
*ph
.numrows
)+u
]);
369 MikMod_free(xmpat
);xmpat
=NULL
;
370 _mm_errno
=MMERR_LOADING_PATTERN
;
376 _mm_fseek(modreader
,ph
.packsize
,SEEK_CUR
);
379 if(_mm_eof(modreader
)) {
380 MikMod_free(xmpat
);xmpat
=NULL
;
381 _mm_errno
=MMERR_LOADING_PATTERN
;
385 for(v
=0;v
<of
.numchn
;v
++)
386 of
.tracks
[numtrk
++]=XM_Convert(&xmpat
[v
*ph
.numrows
],ph
.numrows
);
388 MikMod_free(xmpat
);xmpat
=NULL
;
390 for(v
=0;v
<of
.numchn
;v
++)
391 of
.tracks
[numtrk
++]=XM_Convert(NULL
,ph
.numrows
);
397 if(!(xmpat
=(XMNOTE
*)MikMod_calloc(64*of
.numchn
,sizeof(XMNOTE
)))) return 0;
398 for(v
=0;v
<of
.numchn
;v
++)
399 of
.tracks
[numtrk
++]=XM_Convert(&xmpat
[v
*64],64);
400 MikMod_free(xmpat
);xmpat
=NULL
;
406 static void FixEnvelope(ENVPT
*cur
, int pts
)
411 /* Some broken XM editing program will only save the low byte
412 of the position value. Try to compensate by adding the
413 missing high byte. */
418 for (u
= 1; u
< pts
; u
++, prev
++, cur
++) {
419 if (cur
->pos
< prev
->pos
) {
420 if (cur
->pos
< 0x100) {
421 if (cur
->pos
> old
) /* same hex century */
422 tmp
= cur
->pos
+ (prev
->pos
- old
);
424 tmp
= cur
->pos
| ((prev
->pos
+ 0x100) & 0xff00);
428 fprintf(stderr
, "\rbroken envelope position(%d/%d), %d %d -> %d\n",
429 u
, pts
, prev
->pos
, old
, cur
->pos
);
433 /* different brokenness style... fix unknown */
434 fprintf(stderr
, "\rbroken envelope position(%d/%d), %d %d\n",
435 u
, pts
, old
, cur
->pos
);
444 static int LoadInstruments(void)
451 if(!AllocInstruments()) return 0;
453 for(t
=0;t
<of
.numins
;t
++,d
++) {
457 memset(d
->samplenumber
,0xff,INSTNOTES
*sizeof(UWORD
));
459 /* read instrument header */
460 headend
= _mm_ftell(modreader
);
461 ih
.size
= _mm_read_I_ULONG(modreader
);
463 ck
= _mm_ftell(modreader
);
464 _mm_fseek(modreader
,0,SEEK_END
);
465 if ((headend
<0) || (_mm_ftell(modreader
)<headend
) || (headend
<ck
)) {
466 _mm_fseek(modreader
,ck
,SEEK_SET
);
469 _mm_fseek(modreader
,ck
,SEEK_SET
);
470 _mm_read_string(ih
.name
, 22, modreader
);
471 ih
.type
= _mm_read_UBYTE(modreader
);
472 ih
.numsmp
= _mm_read_I_UWORD(modreader
);
474 d
->insname
= DupStr(ih
.name
,22,1);
476 if((SWORD
)ih
.size
>29) {
477 ih
.ssize
= _mm_read_I_ULONG(modreader
);
478 if(((SWORD
)ih
.numsmp
>0)&&(ih
.numsmp
<=XMNOTECNT
)) {
482 _mm_read_UBYTES (pth
.what
,XMNOTECNT
,modreader
);
483 _mm_read_I_UWORDS (pth
.volenv
, XMENVCNT
, modreader
);
484 _mm_read_I_UWORDS (pth
.panenv
, XMENVCNT
, modreader
);
485 pth
.volpts
= _mm_read_UBYTE(modreader
);
486 pth
.panpts
= _mm_read_UBYTE(modreader
);
487 pth
.volsus
= _mm_read_UBYTE(modreader
);
488 pth
.volbeg
= _mm_read_UBYTE(modreader
);
489 pth
.volend
= _mm_read_UBYTE(modreader
);
490 pth
.pansus
= _mm_read_UBYTE(modreader
);
491 pth
.panbeg
= _mm_read_UBYTE(modreader
);
492 pth
.panend
= _mm_read_UBYTE(modreader
);
493 pth
.volflg
= _mm_read_UBYTE(modreader
);
494 pth
.panflg
= _mm_read_UBYTE(modreader
);
495 pth
.vibflg
= _mm_read_UBYTE(modreader
);
496 pth
.vibsweep
= _mm_read_UBYTE(modreader
);
497 pth
.vibdepth
= _mm_read_UBYTE(modreader
);
498 pth
.vibrate
= _mm_read_UBYTE(modreader
);
499 pth
.volfade
= _mm_read_I_UWORD(modreader
);
501 /* read the remainder of the header
502 (2 bytes for 1.03, 22 for 1.04) */
503 if (headend
>=_mm_ftell(modreader
)) for(u
=headend
-_mm_ftell(modreader
);u
;u
--) (void)_mm_read_UBYTE(modreader
);
505 /* we can't trust the envelope point count here, as some
506 modules have incorrect values (K_OSPACE.XM reports 32 volume
507 points, for example). */
508 if(pth
.volpts
>XMENVCNT
/2) pth
.volpts
=XMENVCNT
/2;
509 if(pth
.panpts
>XMENVCNT
/2) pth
.panpts
=XMENVCNT
/2;
511 if((_mm_eof(modreader
))||(pth
.volpts
>XMENVCNT
/2)||(pth
.panpts
>XMENVCNT
/2)) {
512 if(nextwav
) { MikMod_free(nextwav
);nextwav
=NULL
; }
513 if(wh
) { MikMod_free(wh
);wh
=NULL
; }
514 _mm_errno
= MMERR_LOADING_SAMPLEINFO
;
518 for(u
=0;u
<XMNOTECNT
;u
++)
519 d
->samplenumber
[u
]=pth
.what
[u
]+of
.numsmp
;
520 d
->volfade
= pth
.volfade
;
522 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
523 #define XM_ProcessEnvelope(name) \
524 for (u = 0; u < (XMENVCNT >> 1); u++) { \
525 d-> name##env[u].pos = pth. name##env[u << 1]; \
526 d-> name##env[u].val = pth. name##env[(u << 1)+ 1]; \
528 if (pth. name##flg&1) d-> name##flg|=EF_ON; \
529 if (pth. name##flg&2) d-> name##flg|=EF_SUSTAIN; \
530 if (pth. name##flg&4) d-> name##flg|=EF_LOOP; \
531 d-> name##susbeg=d-> name##susend=pth. name##sus; \
532 d-> name##beg=pth. name##beg; \
533 d-> name##end=pth. name##end; \
534 d-> name##pts=pth. name##pts; \
536 /* scale envelope */ \
537 for (p=0;p<XMENVCNT/2;p++) \
538 d-> name##env[p].val<<=2; \
540 if ((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \
541 d-> name##flg&=~EF_ON
543 #define XM_ProcessEnvelope(name) \
544 for (u = 0; u < (XMENVCNT >> 1); u++) { \
545 d-> name/**/env[u].pos = pth. name/**/env[u << 1]; \
546 d-> name/**/env[u].val = pth. name/**/env[(u << 1)+ 1]; \
548 if (pth. name/**/flg&1) d-> name/**/flg|=EF_ON; \
549 if (pth. name/**/flg&2) d-> name/**/flg|=EF_SUSTAIN; \
550 if (pth. name/**/flg&4) d-> name/**/flg|=EF_LOOP; \
551 d-> name/**/susbeg=d-> name/**/susend= \
553 d-> name/**/beg=pth. name/**/beg; \
554 d-> name/**/end=pth. name/**/end; \
555 d-> name/**/pts=pth. name/**/pts; \
557 /* scale envelope */ \
558 for (p=0;p<XMENVCNT/2;p++) \
559 d-> name/**/env[p].val<<=2; \
561 if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
562 d-> name/**/flg&=~EF_ON
565 XM_ProcessEnvelope(vol
);
566 XM_ProcessEnvelope(pan
);
567 #undef XM_ProcessEnvelope
569 if (d
->volflg
& EF_ON
)
570 FixEnvelope(d
->volenv
, d
->volpts
);
571 if (d
->panflg
& EF_ON
)
572 FixEnvelope(d
->panenv
, d
->panpts
);
574 /* Samples are stored outside the instrument struct now, so we
575 have to load them all into a temp area, count the of.numsmp
576 along the way and then do an AllocSamples() and move
578 if(mh
->version
>0x0103) next
= 0;
579 for(u
=0;u
<ih
.numsmp
;u
++,s
++) {
580 /* Allocate more room for sample information if necessary */
581 if(of
.numsmp
+u
==wavcnt
) {
583 if(!(nextwav
=MikMod_realloc(nextwav
,wavcnt
*sizeof(ULONG
)))){
584 if(wh
) { MikMod_free(wh
);wh
=NULL
; }
585 _mm_errno
= MMERR_OUT_OF_MEMORY
;
588 if(!(wh
=MikMod_realloc(wh
,wavcnt
*sizeof(XMWAVHEADER
)))) {
589 MikMod_free(nextwav
);nextwav
=NULL
;
590 _mm_errno
= MMERR_OUT_OF_MEMORY
;
593 s
=wh
+(wavcnt
-XM_SMPINCR
);
596 s
->length
=_mm_read_I_ULONG (modreader
);
597 s
->loopstart
=_mm_read_I_ULONG (modreader
);
598 s
->looplength
=_mm_read_I_ULONG (modreader
);
599 s
->volume
=_mm_read_UBYTE (modreader
);
600 s
->finetune
=_mm_read_SBYTE (modreader
);
601 s
->type
=_mm_read_UBYTE (modreader
);
602 s
->panning
=_mm_read_UBYTE (modreader
);
603 s
->relnote
=_mm_read_SBYTE (modreader
);
604 s
->vibtype
= pth
.vibflg
;
605 s
->vibsweep
= pth
.vibsweep
;
606 s
->vibdepth
= pth
.vibdepth
*4;
607 s
->vibrate
= pth
.vibrate
;
608 s
->reserved
=_mm_read_UBYTE (modreader
);
609 _mm_read_string(s
->samplename
, 22, modreader
);
611 nextwav
[of
.numsmp
+u
]=next
;
614 if(_mm_eof(modreader
)) {
615 MikMod_free(nextwav
);MikMod_free(wh
);
616 nextwav
=NULL
;wh
=NULL
;
617 _mm_errno
= MMERR_LOADING_SAMPLEINFO
;
622 if(mh
->version
>0x0103) {
623 for(u
=0;u
<ih
.numsmp
;u
++)
624 nextwav
[of
.numsmp
++]+=_mm_ftell(modreader
);
625 _mm_fseek(modreader
,next
,SEEK_CUR
);
627 of
.numsmp
+=ih
.numsmp
;
629 /* read the remainder of the header */
630 ck
= _mm_ftell(modreader
);
631 _mm_fseek(modreader
,0,SEEK_END
);
632 if ((headend
<0) || (_mm_ftell(modreader
)<headend
) || (headend
<ck
)) {
633 _mm_fseek(modreader
,ck
,SEEK_SET
);
636 _mm_fseek(modreader
,ck
,SEEK_SET
);
637 for(u
=headend
-_mm_ftell(modreader
);u
;u
--) (void)_mm_read_UBYTE(modreader
);
639 if(_mm_eof(modreader
)) {
640 MikMod_free(nextwav
);MikMod_free(wh
);
641 nextwav
=NULL
;wh
=NULL
;
642 _mm_errno
= MMERR_LOADING_SAMPLEINFO
;
651 if(nextwav
) { MikMod_free(nextwav
);nextwav
=NULL
; }
652 if(wh
) { MikMod_free(wh
);wh
=NULL
; }
653 _mm_errno
= MMERR_LOADING_SAMPLEINFO
;
660 static int XM_Load(int curious
)
666 char tracker
[21],modtype
[60];
669 /* try to read module header */
670 _mm_read_string(mh
->id
,17,modreader
);
671 _mm_read_string(mh
->songname
,21,modreader
);
672 _mm_read_string(mh
->trackername
,20,modreader
);
673 mh
->version
=_mm_read_I_UWORD(modreader
);
674 if((mh
->version
<0x102)||(mh
->version
>0x104)) {
675 _mm_errno
=MMERR_NOT_A_MODULE
;
678 mh
->headersize
=_mm_read_I_ULONG(modreader
);
679 mh
->songlength
=_mm_read_I_UWORD(modreader
);
680 mh
->restart
=_mm_read_I_UWORD(modreader
);
681 mh
->numchn
=_mm_read_I_UWORD(modreader
);
682 mh
->numpat
=_mm_read_I_UWORD(modreader
);
683 mh
->numins
=_mm_read_I_UWORD(modreader
);
684 mh
->flags
=_mm_read_I_UWORD(modreader
);
685 mh
->tempo
=_mm_read_I_UWORD(modreader
);
686 mh
->bpm
=_mm_read_I_UWORD(modreader
);
688 _mm_errno
=MMERR_NOT_A_MODULE
;
691 _mm_read_UBYTES(mh
->orders
,mh
->headersize
-20,modreader
);
693 if(_mm_eof(modreader
)) {
694 _mm_errno
= MMERR_LOADING_HEADER
;
698 /* set module variables */
699 of
.initspeed
= mh
->tempo
;
700 of
.inittempo
= mh
->bpm
;
701 strncpy(tracker
,mh
->trackername
,20);tracker
[20]=0;
702 for(t
=20;(tracker
[t
]<=' ')&&(t
>=0);t
--) tracker
[t
]=0;
704 /* some modules have the tracker name empty */
706 strcpy(tracker
,"Unknown tracker");
709 snprintf(modtype
,60,"%s (XM format %d.%02d)",
710 tracker
,mh
->version
>>8,mh
->version
&0xff);
712 sprintf(modtype
,"%s (XM format %d.%02d)",
713 tracker
,mh
->version
>>8,mh
->version
&0xff);
715 of
.modtype
= StrDup(modtype
);
716 of
.numchn
= mh
->numchn
;
717 of
.numpat
= mh
->numpat
;
718 of
.numtrk
= (UWORD
)of
.numpat
*of
.numchn
; /* get number of channels */
719 of
.songname
= DupStr(mh
->songname
,20,1);
720 of
.numpos
= mh
->songlength
; /* copy the songlength */
721 of
.reppos
= mh
->restart
<mh
->songlength
?mh
->restart
:0;
722 of
.numins
= mh
->numins
;
723 of
.flags
|= UF_XMPERIODS
| UF_INST
| UF_NOWRAP
| UF_FT2QUIRKS
|
725 if(mh
->flags
&1) of
.flags
|= UF_LINEAR
;
728 memset(of
.chanvol
,64,of
.numchn
); /* store channel volumes */
730 if(!AllocPositions(of
.numpos
+1)) return 0;
731 for(t
=0;t
<of
.numpos
;t
++)
732 of
.positions
[t
]=mh
->orders
[t
];
734 /* We have to check for any pattern numbers in the order list greater than
735 the number of patterns total. If one or more is found, we set it equal to
736 the pattern total and make a dummy pattern to workaround the problem */
737 for(t
=0;t
<of
.numpos
;t
++) {
738 if(of
.positions
[t
]>=of
.numpat
) {
739 of
.positions
[t
]=of
.numpat
;
744 of
.numpat
++;of
.numtrk
+=of
.numchn
;
747 if(mh
->version
<0x0104) {
748 if(!LoadInstruments()) return 0;
749 if(!LoadPatterns(dummypat
)) return 0;
750 for(t
=0;t
<of
.numsmp
;t
++)
751 nextwav
[t
]+=_mm_ftell(modreader
);
753 if(!LoadPatterns(dummypat
)) return 0;
754 if(!LoadInstruments()) return 0;
757 if(!AllocSamples()) {
758 MikMod_free(nextwav
);MikMod_free(wh
);
759 nextwav
=NULL
;wh
=NULL
;
764 for(u
=0;u
<of
.numsmp
;u
++,q
++,s
++) {
765 q
->samplename
= DupStr(s
->samplename
,22,1);
766 q
->length
= s
->length
;
767 q
->loopstart
= s
->loopstart
;
768 q
->loopend
= s
->loopstart
+s
->looplength
;
769 q
->volume
= s
->volume
;
770 q
->speed
= s
->finetune
+128;
771 q
->panning
= s
->panning
;
772 q
->seekpos
= nextwav
[u
];
773 q
->vibtype
= s
->vibtype
;
774 q
->vibsweep
= s
->vibsweep
;
775 q
->vibdepth
= s
->vibdepth
;
776 q
->vibrate
= s
->vibrate
;
784 q
->flags
|=SF_OWNPAN
|SF_DELTA
|SF_SIGNED
;
785 if(s
->type
&0x3) q
->flags
|=SF_LOOP
;
786 if(s
->type
&0x2) q
->flags
|=SF_BIDI
;
787 if(s
->type
&0x10) q
->flags
|=SF_16BITS
;
792 for(u
=0;u
<of
.numins
;u
++,d
++)
793 for(t
=0;t
<XMNOTECNT
;t
++) {
794 if (d
->samplenumber
[t
]>=of
.numsmp
)
795 d
->samplenote
[t
]=255;
797 int note
=t
+s
[d
->samplenumber
[t
]].relnote
;
798 d
->samplenote
[t
]=(note
<0)?0:note
;
802 MikMod_free(wh
);MikMod_free(nextwav
);
803 wh
=NULL
;nextwav
=NULL
;
807 static CHAR
*XM_LoadTitle(void)
811 _mm_fseek(modreader
,17,SEEK_SET
);
812 if(!_mm_read_UBYTES(s
,21,modreader
)) return NULL
;
814 return(DupStr(s
,21,1));
817 /*========== Loader information */
819 MIKMODAPI MLOADER load_xm
={
822 "XM (FastTracker 2)",