OSDN Git Service

autoreconf
[timidity41/timidity41.git] / libunimod / load_gdm.c
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   General DigiMusic (GDM) module loader
26
27 ==============================================================================*/
28
29 /*
30
31    Written by Kev Vance<kvance@zeux.org>
32    based on the file format description written by 'MenTaLguY'
33    <mental@kludge.org>
34
35  */
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include <stdio.h>
42 #include <string.h>
43
44 #include "unimod_priv.h"
45
46 typedef struct GDMNOTE
47   {
48     UBYTE note;
49     UBYTE samp;
50     struct
51       {
52         UBYTE effect;
53         UBYTE param;
54       }
55     effect[4];
56   }
57 GDMNOTE;
58
59 typedef GDMNOTE GDMTRACK[64];
60
61 typedef struct GDMHEADER
62   {
63     CHAR id1[4];
64     CHAR songname[32];
65     CHAR author[32];
66     CHAR eofmarker[3];
67     CHAR id2[4];
68
69     UBYTE majorver;
70     UBYTE minorver;
71     UWORD trackerid;
72     UBYTE t_majorver;
73     UBYTE t_minorver;
74     UBYTE pantable[32];
75     UBYTE mastervol;
76     UBYTE mastertempo;
77     UBYTE masterbpm;
78     UWORD flags;
79
80     ULONG orderloc;
81     UBYTE ordernum;
82     ULONG patternloc;
83     UBYTE patternnum;
84     ULONG samhead;
85     ULONG samdata;
86     UBYTE samnum;
87     ULONG messageloc;
88     ULONG messagelen;
89     ULONG scrollyloc;
90     UWORD scrollylen;
91     ULONG graphicloc;
92     UWORD graphiclen;
93   }
94 GDMHEADER;
95
96 typedef struct GDMSAMPLE
97   {
98     CHAR sampname[32];
99     CHAR filename[13];
100     UBYTE ems;
101     ULONG length;
102     ULONG loopbeg;
103     ULONG loopend;
104     UBYTE flags;
105     UWORD c4spd;
106     UBYTE vol;
107     UBYTE pan;
108   }
109 GDMSAMPLE;
110
111 static GDMHEADER *mh = NULL;    /* pointer to GDM header */
112 static GDMNOTE *gdmbuf = NULL;  /* pointer to a complete GDM pattern */
113
114 CHAR GDM_Version[] = "General DigiMusic 1.xx";
115
116 BOOL 
117 GDM_Test (void)
118 {
119   /* test for gdm magic numbers */
120   UBYTE id[4];
121
122   _mm_fseek (modreader, 0x00, SEEK_SET);
123   if (!_mm_read_UBYTES (id, 4, modreader))
124     return 0;
125   if (!memcmp (id, "GDM\xfe", 4))
126     {
127       _mm_fseek (modreader, 71, SEEK_SET);
128       if (!_mm_read_UBYTES (id, 4, modreader))
129         return 0;
130       if (!memcmp (id, "GMFS", 4))
131         return 1;
132     }
133   return 0;
134 }
135
136 BOOL 
137 GDM_Init (void)
138 {
139   if (!(gdmbuf = (GDMNOTE *) _mm_malloc (32 * 64 * sizeof (GDMNOTE))))
140     return 0;
141   if (!(mh = (GDMHEADER *) _mm_malloc (sizeof (GDMHEADER))))
142     return 0;
143
144   return 1;
145 }
146
147 void 
148 GDM_Cleanup (void)
149 {
150   _mm_free (mh);
151   _mm_free (gdmbuf);
152 }
153
154 BOOL 
155 GDM_ReadPattern (void)
156 {
157   int pos, flag, ch, i, maxch;
158   GDMNOTE n;
159   UWORD length, x = 0;
160
161   /* get pattern length */
162   length = _mm_read_I_UWORD (modreader) - 2;
163
164   /* clear pattern data */
165   memset (gdmbuf, 255, 32 * 64 * sizeof (GDMNOTE));
166   pos = 0;
167   maxch = 0;
168
169   while (x < length)
170     {
171       memset (&n, 255, sizeof (GDMNOTE));
172       flag = _mm_read_UBYTE (modreader);
173       x++;
174
175       if (_mm_eof (modreader))
176         {
177           _mm_errno = MMERR_LOADING_PATTERN;
178           return 0;
179         }
180
181       ch = flag & 31;
182       if (ch > maxch)
183         maxch = ch;
184       if (!flag)
185         {
186           pos++;
187           continue;
188         }
189       if (flag & 0x60)
190         {
191           if (flag & 0x20)
192             {
193               /* new note */
194               n.note = _mm_read_UBYTE (modreader) & 127;
195               n.samp = _mm_read_UBYTE (modreader);
196               x += 2;
197             }
198           if (flag & 0x40)
199             {
200               do
201                 {
202                   /* effect channel set */
203                   i = _mm_read_UBYTE (modreader);
204                   n.effect[i >> 6].effect = i & 31;
205                   n.effect[i >> 6].param = _mm_read_UBYTE (modreader);
206                   x += 2;
207                 }
208               while (i & 32);
209             }
210           memcpy (gdmbuf + (64U * ch) + pos, &n, sizeof (n));
211         }
212     }
213   return 1;
214 }
215
216 UBYTE *
217 GDM_ConvertTrack (GDMNOTE * tr)
218 {
219   int t, i = 0;
220   UBYTE note, ins;
221
222   UniReset ();
223   for (t = 0; t < 64; t++)
224     {
225       note = tr[t].note;
226       ins = tr[t].samp;
227
228       if ((ins) && (ins != 255))
229         UniInstrument (ins - 1);
230       if (note != 255)
231         {
232           UniNote (((note >> 4) * OCTAVE) + (note & 0xf) - 1);
233         }
234       for (i = 0; i < 4; i++)
235         {
236           switch (tr[t].effect[i].effect)
237             {
238             case 1:             /* toneslide up */
239               UniEffect (UNI_S3MEFFECTF, tr[t].effect[i].param);
240               break;
241             case 2:             /* toneslide down */
242               UniEffect (UNI_S3MEFFECTE, tr[t].effect[i].param);
243               break;
244             case 3:             /* glissando to note */
245               UniEffect (UNI_ITEFFECTG, tr[t].effect[i].param);
246               break;
247             case 4:             /* vibrato */
248               UniEffect (UNI_ITEFFECTH, tr[t].effect[i].param);
249               break;
250             case 5:             /* portamento+volslide */
251               UniEffect (UNI_ITEFFECTG, 0);
252               UniEffect (UNI_S3MEFFECTD, tr[t].effect[i].param);
253               break;
254             case 6:             /* vibrato+volslide */
255               UniEffect (UNI_ITEFFECTH, 0);
256               UniEffect (UNI_S3MEFFECTD, tr[t].effect[i].param);
257               break;
258             case 7:             /* tremolo */
259               UniEffect (UNI_S3MEFFECTR, tr[t].effect[i].param);
260               break;
261             case 8:             /* tremor */
262               UniEffect (UNI_S3MEFFECTI, tr[t].effect[i].param);
263               break;
264             case 9:             /* offset */
265               UniPTEffect (0x09, tr[t].effect[i].param);
266               break;
267             case 0x0a:          /* volslide */
268               UniEffect (UNI_S3MEFFECTD, tr[t].effect[i].param);
269               break;
270             case 0x0b:          /* jump to order */
271               UniPTEffect (0x0b, tr[t].effect[i].param);
272               break;
273             case 0x0c:          /* volume set */
274               UniPTEffect (0x0c, tr[t].effect[i].param);
275               break;
276             case 0x0d:          /* pattern break */
277               UniPTEffect (0x0d, tr[t].effect[i].param);
278               break;
279             case 0x0e:          /* extended */
280               switch (tr[t].effect[i].param & 0xf0)
281                 {
282                 case 0x10:      /* fine portamento up */
283                   UniEffect (UNI_S3MEFFECTF,
284                              0x0f | ((tr[t].effect[i].param << 4) & 0x0f));
285                   break;
286                 case 0x20:      /* fine portamento down */
287                   UniEffect (UNI_S3MEFFECTE,
288                              0xf0 | (tr[t].effect[i].param & 0x0f));
289                   break;
290                 case 0x30:      /* glissando control */
291                   UniEffect (SS_GLISSANDO,
292                              tr[t].effect[i].param & 0x0f);
293                   break;
294                 case 0x40:      /* vibrato waveform */
295                   UniEffect (SS_VIBWAVE,
296                              tr[t].effect[i].param & 0x0f);
297                   break;
298                 case 0x50:      /* set c4spd */
299                   UniEffect (SS_FINETUNE,
300                              tr[t].effect[i].param & 0x0f);
301                   break;
302                 case 0x60:      /* loop fun */
303                   UniEffect (UNI_ITEFFECTS0,
304                              (tr[t].effect[i].param & 0x0f) | 0xb0);
305                   break;
306                 case 0x70:      /* tremolo waveform */
307                   UniEffect (SS_TREMWAVE,
308                              tr[t].effect[i].param & 0x0f);
309                   break;
310                 case 0x80:      /* extra fine porta up */
311                   UniEffect (UNI_S3MEFFECTF,
312                              0x0e | ((tr[t].effect[i].param << 4) & 0x0f));
313                   break;
314                 case 0x90:      /* extra fine porta down */
315                   UniEffect (UNI_S3MEFFECTE,
316                              0xe0 | (tr[t].effect[i].param & 0x0f));
317                   break;
318                 case 0xa0:      /* fine volslide up */
319                   UniEffect (UNI_S3MEFFECTD,
320                              0x0f | ((tr[t].effect[i].param << 4) & 0x0f));
321                   break;
322                 case 0xb0:      /* fine volslide down */
323                   UniEffect (UNI_S3MEFFECTE,
324                              0xf0 | (tr[t].effect[i].param & 0x0f));
325                   break;
326                 case 0xc0:      /* note cut */
327                 case 0xd0:      /* note delay */
328                 case 0xe0:      /* extend row */
329                   UniPTEffect (0xe, tr[t].effect[i].param);
330                   break;
331                 }
332               break;
333             case 0x0f:          /* set tempo */
334               UniEffect (UNI_S3MEFFECTA, tr[t].effect[i].param);
335               break;
336             case 0x10:          /* arpeggio */
337               UniPTEffect (0x0, tr[t].effect[i].param);
338               break;
339             case 0x12:          /* retrigger */
340               UniEffect (UNI_S3MEFFECTQ, tr[t].effect[i].param);
341               break;
342             case 0x13:          /* set global volume */
343               UniEffect (UNI_XMEFFECTG, tr[t].effect[i].param);
344               break;
345             case 0x14:          /* fine vibrato */
346               UniEffect (UNI_ITEFFECTU, tr[t].effect[i].param);
347               break;
348             case 0x1e:          /* special */
349               switch (tr[t].effect[i].param & 0xf0)
350                 {
351                 case 8: /* set pan position */
352                   if (tr[t].effect[i].param >= 128)
353                     UniPTEffect (0x08, 255);
354                   else
355                     UniPTEffect (0x08, tr[t].effect[i].param << 1);
356                   break;
357                 }
358               break;
359             case 0x1f:          /* set bpm */
360               if (tr[t].effect[i].param >= 0x20)
361                 UniEffect (UNI_S3MEFFECTT, tr[t].effect[i].param);
362               break;
363             }
364         }
365       UniNewline ();
366     }
367   return UniDup ();
368 }
369
370 BOOL 
371 GDM_Load (BOOL curious)
372 {
373   int i, x, u, track;
374   SAMPLE *q;
375   GDMSAMPLE s;
376   ULONG position;
377
378   /* read header */
379   _mm_read_string (mh->id1, 4, modreader);
380   _mm_read_string (mh->songname, 32, modreader);
381   _mm_read_string (mh->author, 32, modreader);
382   _mm_read_string (mh->eofmarker, 3, modreader);
383   _mm_read_string (mh->id2, 4, modreader);
384
385   mh->majorver = _mm_read_UBYTE (modreader);
386   mh->minorver = _mm_read_UBYTE (modreader);
387   mh->trackerid = _mm_read_I_UWORD (modreader);
388   mh->t_majorver = _mm_read_UBYTE (modreader);
389   mh->t_minorver = _mm_read_UBYTE (modreader);
390   _mm_read_UBYTES (mh->pantable, 32, modreader);
391   mh->mastervol = _mm_read_UBYTE (modreader);
392   mh->mastertempo = _mm_read_UBYTE (modreader);
393   mh->masterbpm = _mm_read_UBYTE (modreader);
394   mh->flags = _mm_read_I_UWORD (modreader);
395
396   mh->orderloc = _mm_read_I_ULONG (modreader);
397   mh->ordernum = _mm_read_UBYTE (modreader);
398   mh->patternloc = _mm_read_I_ULONG (modreader);
399   mh->patternnum = _mm_read_UBYTE (modreader);
400   mh->samhead = _mm_read_I_ULONG (modreader);
401   mh->samdata = _mm_read_I_ULONG (modreader);
402   mh->samnum = _mm_read_UBYTE (modreader);
403   mh->messageloc = _mm_read_I_ULONG (modreader);
404   mh->messagelen = _mm_read_I_ULONG (modreader);
405   mh->scrollyloc = _mm_read_I_ULONG (modreader);
406   mh->scrollylen = _mm_read_I_UWORD (modreader);
407   mh->graphicloc = _mm_read_I_ULONG (modreader);
408   mh->graphiclen = _mm_read_I_UWORD (modreader);
409
410   /* have we ended abruptly? */
411   if (_mm_eof (modreader))
412     {
413       _mm_errno = MMERR_LOADING_HEADER;
414       return 0;
415     }
416
417   /* any orders? */
418   if (mh->ordernum == 255)
419     {
420       _mm_errno = MMERR_LOADING_PATTERN;
421       return 0;
422     }
423
424   /* now we fill */
425   of.modtype = strdup (GDM_Version);
426   of.modtype[18] = mh->majorver + '0';
427   of.modtype[20] = mh->minorver / 10 + '0';
428   of.modtype[21] = mh->minorver % 10 + '0';
429   of.songname = DupStr (mh->songname, 32, 0);
430   of.numpat = mh->patternnum + 1;
431   of.reppos = 0;
432   of.numins = of.numsmp = mh->samnum + 1;
433   of.initspeed = mh->mastertempo;
434   of.inittempo = mh->masterbpm;
435   of.initvolume = mh->mastervol << 1;
436   of.flags |= UF_S3MSLIDES;
437
438   /* read the order data */
439   if (!AllocPositions (mh->ordernum + 1))
440     {
441       _mm_errno = MMERR_OUT_OF_MEMORY;
442       return 0;
443     }
444
445   _mm_fseek (modreader, mh->orderloc, SEEK_SET);
446   for (i = 0; i < mh->ordernum + 1; i++)
447     of.positions[i] = _mm_read_UBYTE (modreader);
448
449   of.numpos = 0;
450   for (i = 0; i < mh->ordernum + 1; i++)
451     {
452       of.positions[of.numpos] = of.positions[i];
453       if (of.positions[i] < 254)
454         of.numpos++;
455     }
456
457   /* have we ended abruptly yet? */
458   if (_mm_eof (modreader))
459     {
460       _mm_errno = MMERR_LOADING_HEADER;
461       return 0;
462     }
463
464   /* time to load the samples */
465   if (!AllocSamples ())
466     {
467       _mm_errno = MMERR_OUT_OF_MEMORY;
468       return 0;
469     }
470
471   q = of.samples;
472   position = mh->samdata;
473
474   /* seek to instrument position */
475   _mm_fseek (modreader, mh->samhead, SEEK_SET);
476
477   for (i = 0; i < of.numins; i++)
478     {
479       /* load sample info */
480       _mm_read_UBYTES (s.sampname, 32, modreader);
481       _mm_read_UBYTES (s.filename, 12, modreader);
482       s.ems = _mm_read_UBYTE (modreader);
483       s.length = _mm_read_I_ULONG (modreader);
484       s.loopbeg = _mm_read_I_ULONG (modreader);
485       s.loopend = _mm_read_I_ULONG (modreader);
486       s.flags = _mm_read_UBYTE (modreader);
487       s.c4spd = _mm_read_I_UWORD (modreader);
488       s.vol = _mm_read_UBYTE (modreader);
489       s.pan = _mm_read_UBYTE (modreader);
490
491       if (_mm_eof (modreader))
492         {
493           _mm_errno = MMERR_LOADING_SAMPLEINFO;
494           return 0;
495         }
496       q->samplename = DupStr (s.sampname, 32, 0);
497       q->speed = s.c4spd;
498       q->length = s.length;
499       q->loopstart = s.loopbeg;
500       q->loopend = s.loopend;
501       q->volume = s.vol;
502       q->panning = s.pan;
503       q->seekpos = position;
504
505       position += s.length;
506
507       if (s.flags & 1)
508         q->flags |= SF_LOOP;
509       if (s.flags & 2)
510         q->flags |= SF_16BITS;
511       if (s.flags & 16)
512         q->flags |= SF_STEREO;
513       q++;
514     }
515
516   /* set the panning */
517   for (i = x = 0; i < 32; i++)
518     {
519       of.panning[i] = mh->pantable[i];
520       if (!of.panning[i])
521         of.panning[i] = PAN_LEFT;
522       else if (of.panning[i] == 8)
523         of.panning[i] = PAN_CENTER;
524       else if (of.panning[i] == 15)
525         of.panning[i] = PAN_RIGHT;
526       else if (of.panning[i] == 16)
527         of.panning[i] = PAN_SURROUND;
528       else if (of.panning[i] == 255)
529         of.panning[i] = 128;
530       else
531         of.panning[i] <<= 3;
532       of.panning[i] = PAN_CENTER;
533       if (mh->pantable[i] != 255)
534         x = i;
535     }
536
537   of.numchn = x + 1;
538   if (of.numchn < 1)
539     of.numchn = 1;              /* for broken counts */
540
541   /* load the pattern info */
542   of.numtrk = of.numpat * of.numchn;
543
544   /* jump to patterns */
545   _mm_fseek (modreader, mh->patternloc, SEEK_SET);
546
547   if (!AllocTracks ())
548     {
549       _mm_errno = MMERR_OUT_OF_MEMORY;
550       return 0;
551     }
552
553   if (!AllocPatterns ())
554     {
555       _mm_errno = MMERR_OUT_OF_MEMORY;
556       return 0;
557     }
558
559   for (i = track = 0; i < of.numpat; i++)
560     {
561       if (!GDM_ReadPattern ())
562         {
563           _mm_errno = MMERR_LOADING_PATTERN;
564           return 0;
565         }
566       for (u = 0; u < of.numchn; u++, track++)
567         {
568           of.tracks[track] = GDM_ConvertTrack (&gdmbuf[u << 6]);
569           if (!of.tracks[track])
570             {
571               _mm_errno = MMERR_LOADING_TRACK;
572               return 0;
573             }
574         }
575     }
576   return 1;
577 }
578
579 CHAR *
580 GDM_LoadTitle (void)
581 {
582   CHAR s[32];
583
584   _mm_fseek (modreader, 4, SEEK_SET);
585   if (!_mm_read_UBYTES (s, 32, modreader))
586     return NULL;
587
588   return DupStr (s, 28, 0);
589 }
590
591 MLOADER load_gdm =
592 {
593   NULL,
594   "GDM",
595   "GDM (General DigiMusic)",
596   GDM_Init,
597   GDM_Test,
598   GDM_Load,
599   GDM_Cleanup,
600   GDM_LoadTitle
601 };
602
603 /* ex:set ts=4: */