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