comparison playercode/load_xm.c @ 4:5d614bcc4287

Initial entry of mikmod into the CVS tree.
author darius
date Fri, 23 Jan 1998 16:05:08 +0000
parents
children
comparison
equal deleted inserted replaced
3:71e20a32bd84 4:5d614bcc4287
1 /*
2
3 Name: LOAD_XM.C
4
5 Description:
6 Fasttracker (XM) module loader
7
8 Portability:
9 All systems - all compilers (hopefully)
10
11 If this module is found to not be portable to any particular platform,
12 please contact Jake Stine at dracoirs@epix.net (see MIKMOD.TXT for
13 more information on contacting the author).
14
15 */
16
17 #include <string.h>
18 #include "mikmod.h"
19
20 /**************************************************************************
21 **************************************************************************/
22
23
24 typedef struct XMHEADER
25 { CHAR id[17]; // ID text: 'Extended module: '
26 CHAR songname[21]; // Module name, padded with zeroes and 0x1a at the end
27 CHAR trackername[20]; // Tracker name
28 UWORD version; // (word) Version number, hi-byte major and low-byte minor
29 ULONG headersize; // Header size
30 UWORD songlength; // (word) Song length (in patten order table)
31 UWORD restart; // (word) Restart position
32 UWORD numchn; // (word) Number of channels (2,4,6,8,10,...,32)
33 UWORD numpat; // (word) Number of patterns (max 256)
34 UWORD numins; // (word) Number of instruments (max 128)
35 UWORD flags; // (word) Flags: bit 0: 0 = Amiga frequency table (see below) 1 = Linear frequency table
36 UWORD tempo; // (word) Default tempo
37 UWORD bpm; // (word) Default BPM
38 UBYTE orders[256]; // (byte) Pattern order table
39 } XMHEADER;
40
41
42 typedef struct XMINSTHEADER
43 { ULONG size; // (dword) Instrument size
44 CHAR name[22]; // (char) Instrument name
45 UBYTE type; // (byte) Instrument type (always 0)
46 UWORD numsmp; // (word) Number of samples in instrument
47 ULONG ssize; //
48 } XMINSTHEADER;
49
50
51 typedef struct XMPATCHHEADER
52 { UBYTE what[96]; // (byte) Sample number for all notes
53 UWORD volenv[24]; // (byte) Points for volume envelope
54 UWORD panenv[24]; // (byte) Points for panning envelope
55 UBYTE volpts; // (byte) Number of volume points
56 UBYTE panpts; // (byte) Number of panning points
57 UBYTE volsus; // (byte) Volume sustain point
58 UBYTE volbeg; // (byte) Volume loop start point
59 UBYTE volend; // (byte) Volume loop end point
60 UBYTE pansus; // (byte) Panning sustain point
61 UBYTE panbeg; // (byte) Panning loop start point
62 UBYTE panend; // (byte) Panning loop end point
63 UBYTE volflg; // (byte) Volume type: bit 0: On; 1: Sustain; 2: Loop
64 UBYTE panflg; // (byte) Panning type: bit 0: On; 1: Sustain; 2: Loop
65 UBYTE vibflg; // (byte) Vibrato type
66 UBYTE vibsweep; // (byte) Vibrato sweep
67 UBYTE vibdepth; // (byte) Vibrato depth
68 UBYTE vibrate; // (byte) Vibrato rate
69 UWORD volfade; // (word) Volume fadeout
70 UWORD reserved[11]; // (word) Reserved
71 } XMPATCHHEADER;
72
73
74 typedef struct XMWAVHEADER
75 { ULONG length; // (dword) Sample length
76 ULONG loopstart; // (dword) Sample loop start
77 ULONG looplength; // (dword) Sample loop length
78 UBYTE volume; // (byte) Volume
79 SBYTE finetune; // (byte) Finetune (signed byte -128..+127)
80 UBYTE type; // (byte) Type: Bit 0-1: 0 = No loop, 1 = Forward loop,
81 // 2 = Ping-pong loop;
82 // 4: 16-bit sampledata
83 UBYTE panning; // (byte) Panning (0-255)
84 SBYTE relnote; // (byte) Relative note number (signed byte)
85 UBYTE reserved; // (byte) Reserved
86 CHAR samplename[22]; // (char) Sample name
87
88 UBYTE vibtype; // (byte) Vibrato type
89 UBYTE vibsweep; // (byte) Vibrato sweep
90 UBYTE vibdepth; // (byte) Vibrato depth
91 UBYTE vibrate; // (byte) Vibrato rate
92 } XMWAVHEADER;
93
94
95 typedef struct XMPATHEADE
96 { ULONG size; // (dword) Pattern header length
97 UBYTE packing; // (byte) Packing type (always 0)
98 UWORD numrows; // (word) Number of rows in pattern (1..256)
99 UWORD packsize; // (word) Packed patterndata size
100 } XMPATHEADER;
101
102 typedef struct MTMNOTE
103 { UBYTE a,b,c;
104 } MTMNOTE;
105
106
107 typedef struct XMNOTE
108 { UBYTE note,ins,vol,eff,dat;
109 }XMNOTE;
110
111 /**************************************************************************
112 **************************************************************************/
113
114 static XMNOTE *xmpat = NULL;
115 static XMHEADER *mh = NULL;
116
117 BOOL XM_Test(void)
118 {
119 UBYTE id[17];
120
121 if(!_mm_read_UBYTES(id,17,modfp)) return 0;
122 if(!memcmp(id,"Extended Module: ",17)) return 1;
123 return 0;
124 }
125
126
127 BOOL XM_Init(void)
128 {
129 if(!(mh=(XMHEADER *)_mm_calloc(1,sizeof(XMHEADER)))) return 0;
130 return 1;
131 }
132
133
134 void XM_Cleanup(void)
135 {
136 if(mh!=NULL) free(mh);
137 mh = NULL;
138 }
139
140
141 void XM_ReadNote(XMNOTE *n)
142 {
143 UBYTE cmp;
144
145 memset(n,0,sizeof(XMNOTE));
146
147 cmp = _mm_read_UBYTE(modfp);
148
149 if(cmp&0x80)
150 { if(cmp&1) n->note = _mm_read_UBYTE(modfp);
151 if(cmp&2) n->ins = _mm_read_UBYTE(modfp);
152 if(cmp&4) n->vol = _mm_read_UBYTE(modfp);
153 if(cmp&8) n->eff = _mm_read_UBYTE(modfp);
154 if(cmp&16) n->dat = _mm_read_UBYTE(modfp);
155 }
156 else
157 { n->note = cmp;
158 n->ins = _mm_read_UBYTE(modfp);
159 n->vol = _mm_read_UBYTE(modfp);
160 n->eff = _mm_read_UBYTE(modfp);
161 n->dat = _mm_read_UBYTE(modfp);
162 }
163 }
164
165
166 UBYTE *XM_Convert(XMNOTE *xmtrack,UWORD rows)
167 {
168 int t;
169 UBYTE note,ins,vol,eff,dat;
170
171 UniReset();
172
173 for(t=0; t<rows; t++)
174 { note = xmtrack->note;
175 ins = xmtrack->ins;
176 vol = xmtrack->vol;
177 eff = xmtrack->eff;
178 dat = xmtrack->dat;
179
180 if(note!=0)
181 { if(note==97)
182 { UniWrite(UNI_KEYFADE);
183 UniWrite(0);
184 } else
185 UniNote(note-1);
186 }
187
188 if(ins!=0) UniInstrument(ins-1);
189
190 switch(vol>>4)
191 {
192 case 0x6: // volslide down
193 if(vol&0xf)
194 { UniWrite(UNI_XMEFFECTA);
195 UniWrite(vol&0xf);
196 }
197 break;
198
199 case 0x7: // volslide up
200 if(vol&0xf)
201 { UniWrite(UNI_XMEFFECTA);
202 UniWrite(vol<<4);
203 }
204 break;
205
206 // volume-row fine volume slide is compatible with protracker
207 // EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as
208 // opposed to 'take the last sliding value'.
209
210 case 0x8: // finevol down
211 UniPTEffect(0xe,0xb0 | (vol&0xf));
212 break;
213
214 case 0x9: // finevol up
215 UniPTEffect(0xe,0xa0 | (vol&0xf));
216 break;
217
218 case 0xa: // set vibrato speed
219 UniPTEffect(0x4,vol<<4);
220 break;
221
222 case 0xb: // vibrato
223 UniPTEffect(0x4,vol&0xf);
224 break;
225
226 case 0xc: // set panning
227 UniPTEffect(0x8,vol<<4);
228 break;
229
230 case 0xd: // panning slide left
231 // only slide when data nibble not zero:
232
233 if(vol&0xf)
234 { UniWrite(UNI_XMEFFECTP);
235 UniWrite(vol&0xf);
236 }
237 break;
238
239 case 0xe: // panning slide right
240 // only slide when data nibble not zero:
241
242 if(vol&0xf)
243 { UniWrite(UNI_XMEFFECTP);
244 UniWrite(vol<<4);
245 }
246 break;
247
248 case 0xf: // tone porta
249 UniPTEffect(0x3,vol<<4);
250 break;
251
252 default:
253 if(vol>=0x10 && vol<=0x50)
254 UniPTEffect(0xc,vol-0x10);
255 }
256
257 switch(eff)
258 {
259 case 0x4: // Effect 4: Vibrato
260 UniWrite(UNI_XMEFFECT4);
261 UniWrite(dat);
262 break;
263
264 case 0xa:
265 UniWrite(UNI_XMEFFECTA);
266 UniWrite(dat);
267 break;
268
269 case 0xe:
270 switch(dat>>4)
271 { case 0x1: // XM fine porta up
272 UniWrite(UNI_XMEFFECTE1);
273 UniWrite(dat&0xf);
274 break;
275
276 case 0x2: // XM fine porta down
277 UniWrite(UNI_XMEFFECTE2);
278 UniWrite(dat&0xf);
279 break;
280
281 case 0xa: // XM fine volume up
282 UniWrite(UNI_XMEFFECTEA);
283 UniWrite(dat&0xf);
284 break;
285
286 case 0xb: // XM fine volume down
287 UniWrite(UNI_XMEFFECTEB);
288 UniWrite(dat&0xf);
289 break;
290
291 default:
292 UniPTEffect(0x0e,dat);
293 }
294 break;
295
296 case 'G'-55: // G - set global volume
297 if(dat>64) dat = 64;
298 UniWrite(UNI_XMEFFECTG);
299 UniWrite(dat);
300 break;
301
302 case 'H'-55: // H - global volume slide
303 UniWrite(UNI_XMEFFECTH);
304 UniWrite(dat);
305 break;
306
307 case 'K'-55: // K - keyOff and KeyFade
308 UniWrite(UNI_KEYFADE);
309 UniWrite(dat);
310 break;
311
312 case 'L'-55: // L - set envelope position
313 UniWrite(UNI_XMEFFECTL);
314 UniWrite(dat);
315 break;
316
317 case 'P'-55: // P - panning slide
318 UniWrite(UNI_XMEFFECTP);
319 UniWrite(dat);
320 break;
321
322 case 'R'-55: // R - multi retrig note
323 UniWrite(UNI_S3MEFFECTQ);
324 UniWrite(dat);
325 break;
326
327 case 'T'-55: // T - Tremor !! (== S3M effect I)
328 UniWrite(UNI_S3MEFFECTI);
329 UniWrite(dat);
330 break;
331
332 case 'X'-55:
333 if((dat>>4) == 1) // X1 - Extra Fine Porta up
334 { UniWrite(UNI_XMEFFECTX1);
335 UniWrite(dat & 0xf);
336 } else if((dat>>4) == 2) // X2 - Extra Fine Porta down
337 { UniWrite(UNI_XMEFFECTX2);
338 UniWrite(dat & 0xf);
339 }
340 break;
341
342 default:
343 if(eff <= 0xf)
344 { // Convert pattern jump from Dec to Hex
345 if(eff == 0xd)
346 dat = (((dat&0xf0)>>4)*10)+(dat&0xf);
347 UniPTEffect(eff,dat);
348 }
349 break;
350 }
351
352 UniNewline();
353 xmtrack++;
354 }
355 return UniDup();
356 }
357
358
359
360 BOOL XM_Load(void)
361 {
362 INSTRUMENT *d;
363 SAMPLE *q;
364 XMWAVHEADER *wh,*s;
365 int t,u,v,p,numtrk;
366 long next;
367 ULONG nextwav[256];
368 BOOL dummypat=0;
369
370 // try to read module header
371
372 _mm_read_string(mh->id,17,modfp);
373 _mm_read_string(mh->songname,21,modfp);
374 _mm_read_string(mh->trackername,20,modfp);
375 mh->version =_mm_read_I_UWORD(modfp);
376 mh->headersize =_mm_read_I_ULONG(modfp);
377 mh->songlength =_mm_read_I_UWORD(modfp);
378 mh->restart =_mm_read_I_UWORD(modfp);
379 mh->numchn =_mm_read_I_UWORD(modfp);
380 mh->numpat =_mm_read_I_UWORD(modfp);
381 mh->numins =_mm_read_I_UWORD(modfp);
382 mh->flags =_mm_read_I_UWORD(modfp);
383 mh->tempo =_mm_read_I_UWORD(modfp);
384 mh->bpm =_mm_read_I_UWORD(modfp);
385 _mm_read_UBYTES(mh->orders,256,modfp);
386
387 if(feof(modfp))
388 { _mm_errno = MMERR_LOADING_HEADER;
389 return 0;
390 }
391
392 // set module variables
393 of.initspeed = mh->tempo;
394 of.inittempo = mh->bpm;
395 of.modtype = DupStr(mh->trackername,20);
396 of.numchn = mh->numchn;
397 of.numpat = mh->numpat;
398 of.numtrk = (UWORD)of.numpat*of.numchn; // get number of channels
399 of.songname = DupStr(mh->songname,20); // make a cstr of songname
400 of.numpos = mh->songlength; // copy the songlength
401 of.reppos = mh->restart;
402 of.numins = mh->numins;
403 of.flags |= UF_XMPERIODS | UF_INST;
404 if(mh->flags&1) of.flags |= UF_LINEAR;
405
406 memset(of.chanvol,64,of.numchn); // store channel volumes
407
408 if(!AllocPositions(of.numpos+3)) return 0;
409 for(t=0; t<of.numpos; t++)
410 of.positions[t] = mh->orders[t];
411
412 /*
413 WHY THIS CODE HERE?? I CAN'T REMEMBER!
414
415 Well, I do know why, mikmak! Seems that FT2 doesn't always count blank
416 patterns AT ALL if they are at the END of the song. So, we have to check
417 for any patter numbers in the order list greater than the number of pat-
418 terns total. If one or more is found, we set it equal to the pattern total
419 and make a dummy pattern to accomidate for the discrepency!
420 */
421
422 for(t=0; t<of.numpos; t++)
423 { if(of.positions[t] > of.numpat)
424 { of.positions[t] = of.numpat;
425 dummypat = 1;
426 }
427 }
428
429 if(dummypat) { of.numpat++; of.numtrk+=of.numchn; }
430
431 if(!AllocTracks()) return 0;
432 if(!AllocPatterns()) return 0;
433
434 numtrk = 0;
435 for(t=0; t<mh->numpat; t++)
436 { XMPATHEADER ph;
437
438 ph.size =_mm_read_I_ULONG(modfp);
439 ph.packing =_mm_read_UBYTE(modfp);
440 ph.numrows =_mm_read_I_UWORD(modfp);
441 ph.packsize =_mm_read_I_UWORD(modfp);
442
443 of.pattrows[t] = ph.numrows;
444
445 // Gr8.. when packsize is 0, don't try to load a pattern.. it's empty.
446 // This bug was discovered thanks to Khyron's module..
447
448 if(!(xmpat=(XMNOTE *)_mm_calloc(ph.numrows*of.numchn,sizeof(XMNOTE)))) return 0;
449
450 if(ph.packsize>0)
451 { for(u=0; u<ph.numrows; u++)
452 { for(v=0; v<of.numchn; v++)
453 XM_ReadNote(&xmpat[(v*ph.numrows)+u]);
454 }
455 }
456
457 if(feof(modfp))
458 { _mm_errno = MMERR_LOADING_PATTERN;
459 return 0;
460 }
461
462 for(v=0; v<of.numchn; v++)
463 of.tracks[numtrk++] = XM_Convert(&xmpat[v*ph.numrows],ph.numrows);
464
465 free(xmpat);
466 }
467
468 if(dummypat)
469 { of.pattrows[t] = 64;
470 if(!(xmpat=(XMNOTE *)_mm_calloc(64*of.numchn,sizeof(XMNOTE)))) return 0;
471 for(v=0; v<of.numchn; v++)
472 of.tracks[numtrk++] = XM_Convert(&xmpat[v*64],64);
473 free(xmpat);
474 }
475
476 if(!AllocInstruments()) return 0;
477 if((wh = (XMWAVHEADER *)_mm_calloc(256,sizeof(XMWAVHEADER))) == NULL) return 0;
478 d = of.instruments;
479 s = wh;
480
481
482 for(t=0; t<of.numins; t++)
483 { XMINSTHEADER ih;
484 int headend;
485
486 memset(d->samplenumber,255,120);
487
488 // read instrument header
489
490 headend = _mm_ftell(modfp);
491 ih.size = _mm_read_I_ULONG(modfp);
492 headend += ih.size;
493 _mm_read_string(ih.name, 22, modfp);
494 ih.type = _mm_read_UBYTE(modfp);
495 ih.numsmp = _mm_read_I_UWORD(modfp);
496 d->insname = DupStr(ih.name,22);
497
498 if(ih.size > 29)
499 { ih.ssize = _mm_read_I_ULONG(modfp);
500 if(ih.numsmp > 0)
501 { XMPATCHHEADER pth;
502
503 _mm_read_UBYTES (pth.what, 96, modfp);
504 _mm_read_I_UWORDS (pth.volenv, 24, modfp);
505 _mm_read_I_UWORDS (pth.panenv, 24, modfp);
506 pth.volpts = _mm_read_UBYTE(modfp);
507 pth.panpts = _mm_read_UBYTE(modfp);
508 pth.volsus = _mm_read_UBYTE(modfp);
509 pth.volbeg = _mm_read_UBYTE(modfp);
510 pth.volend = _mm_read_UBYTE(modfp);
511 pth.pansus = _mm_read_UBYTE(modfp);
512 pth.panbeg = _mm_read_UBYTE(modfp);
513 pth.panend = _mm_read_UBYTE(modfp);
514 pth.volflg = _mm_read_UBYTE(modfp);
515 pth.panflg = _mm_read_UBYTE(modfp);
516 pth.vibflg = _mm_read_UBYTE(modfp);
517 pth.vibsweep = _mm_read_UBYTE(modfp);
518 pth.vibdepth = _mm_read_UBYTE(modfp);
519 pth.vibrate = _mm_read_UBYTE(modfp);
520 pth.volfade = _mm_read_I_UWORD(modfp);
521
522 // read the remainder of the header
523 for(u=headend-_mm_ftell(modfp); u; u--) _mm_read_UBYTE(modfp);
524
525 if(feof(modfp))
526 { _mm_errno = MMERR_LOADING_SAMPLEINFO;
527 return 0;
528 }
529
530 for(u=0; u<96; u++)
531 d->samplenumber[u] = pth.what[u] + of.numsmp;
532
533 d->volfade = pth.volfade;
534
535 memcpy(d->volenv,pth.volenv,24);
536 if(pth.volflg & 1) d->volflg |= EF_ON;
537 if(pth.volflg & 2) d->volflg |= EF_SUSTAIN;
538 if(pth.volflg & 4) d->volflg |= EF_LOOP;
539 d->volsusbeg = d->volsusend = pth.volsus;
540 d->volbeg = pth.volbeg;
541 d->volend = pth.volend;
542 d->volpts = pth.volpts;
543
544 // scale volume envelope:
545
546 for(p=0; p<12; p++)
547 d->volenv[p].val <<= 2;
548
549 if((d->volflg & EF_ON) && (d->volpts < 2))
550 d->volflg &= ~EF_ON;
551
552 memcpy(d->panenv,pth.panenv,24);
553 d->panflg = pth.panflg;
554 d->pansusbeg = d->pansusend = pth.pansus;
555 d->panbeg = pth.panbeg;
556 d->panend = pth.panend;
557 d->panpts = pth.panpts;
558
559 // scale panning envelope:
560
561 for(p=0; p<12; p++)
562 d->panenv[p].val <<= 2;
563 if((d->panflg & EF_ON) && (d->panpts < 2))
564 d->panflg &= ~EF_ON;
565
566 next = 0;
567
568 // Samples are stored outside the instrument struct now, so we have
569 // to load them all into a temp area, count the of.numsmp along the
570 // way and then do an AllocSamples() and move everything over
571
572 for(u=0; u<ih.numsmp; u++,s++)
573 { s->length =_mm_read_I_ULONG (modfp);
574 s->loopstart =_mm_read_I_ULONG (modfp);
575 s->looplength =_mm_read_I_ULONG (modfp);
576 s->volume =_mm_read_UBYTE (modfp);
577 s->finetune =_mm_read_SBYTE (modfp);
578 s->type =_mm_read_UBYTE (modfp);
579 s->panning =_mm_read_UBYTE (modfp);
580 s->relnote =_mm_read_SBYTE (modfp);
581 s->vibtype = pth.vibflg;
582 s->vibsweep = pth.vibsweep;
583 s->vibdepth = pth.vibdepth*4;
584 s->vibrate = pth.vibrate;
585
586 s->reserved =_mm_read_UBYTE (modfp);
587 _mm_read_string(s->samplename, 22, modfp);
588
589 nextwav[of.numsmp+u] = next;
590 next += s->length;
591
592 if(feof(modfp))
593 { _mm_errno = MMERR_LOADING_SAMPLEINFO;
594 return 0;
595 }
596 }
597
598 for(u=0; u<ih.numsmp; u++) nextwav[of.numsmp++] += _mm_ftell(modfp);
599 _mm_fseek(modfp,next,SEEK_CUR);
600 }
601 }
602
603 d++;
604 }
605
606 if(!AllocSamples()) return 0;
607 q = of.samples;
608 s = wh;
609
610 for(u=0; u<of.numsmp; u++,q++,s++)
611 { q->samplename = DupStr(s->samplename,22);
612 q->length = s->length;
613 q->loopstart = s->loopstart;
614 q->loopend = s->loopstart+s->looplength;
615 q->volume = s->volume;
616 q->speed = s->finetune+128;
617 q->panning = s->panning;
618 q->seekpos = nextwav[u];
619 q->vibtype = s->vibtype;
620 q->vibsweep = s->vibsweep;
621 q->vibdepth = s->vibdepth;
622 q->vibrate = s->vibrate;
623
624 if(s->type & 0x10)
625 { q->length >>= 1;
626 q->loopstart >>= 1;
627 q->loopend >>= 1;
628 }
629
630 q->flags|=SF_OWNPAN;
631 if(s->type&0x3) q->flags|=SF_LOOP;
632 if(s->type&0x2) q->flags|=SF_BIDI;
633
634 if(s->type&0x10) q->flags|=SF_16BITS;
635 q->flags|=SF_DELTA;
636 q->flags|=SF_SIGNED;
637 }
638
639 d = of.instruments;
640 s = wh;
641 for(u=0; u<of.numins; u++, d++)
642 { /*for(t=0; t<3; t++)
643 if((s[d->samplenumber[t]].relnote / 12) > )
644 { s[d->samplenumber[t]].relnote -= 12;
645 of.samples[d->samplenumber[t]].speed <<= 1;
646 }
647 */
648 for(t=0; t<96; t++)
649 d->samplenote[t] = (d->samplenumber[t]==of.numsmp) ? 255 : (t+s[d->samplenumber[t]].relnote);
650 }
651
652 free(wh);
653 return 1;
654 }
655
656
657
658 CHAR *XM_LoadTitle(void)
659 {
660 CHAR s[21];
661
662 _mm_fseek(modfp,17,SEEK_SET);
663 if(!fread(s,21,1,modfp)) return NULL;
664
665 return(DupStr(s,21));
666 }
667
668
669
670 MLOADER load_xm =
671 { NULL,
672 "XM",
673 "Portable XM loader v0.5",
674 XM_Init,
675 XM_Test,
676 XM_Load,
677 XM_Cleanup,
678 XM_LoadTitle
679 };