1 /* MikMod sound library
2 (c) 1998,1999 Miodrag Vallat and others - see file AUTHORS for
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 General DigiMusic (GDM) module loader
27 ==============================================================================*/
31 Written by Kev Vance<kvance@zeux.org>
32 based on the file format description written by 'MenTaLguY'
44 #include "unimod_priv.h"
46 typedef struct GDMNOTE
59 typedef GDMNOTE GDMTRACK[64];
61 typedef struct GDMHEADER
96 typedef struct GDMSAMPLE
111 static GDMHEADER *mh = NULL; /* pointer to GDM header */
112 static GDMNOTE *gdmbuf = NULL; /* pointer to a complete GDM pattern */
114 CHAR GDM_Version[] = "General DigiMusic 1.xx";
119 /* test for gdm magic numbers */
122 _mm_fseek (modreader, 0x00, SEEK_SET);
123 if (!_mm_read_UBYTES (id, 4, modreader))
125 if (!memcmp (id, "GDM\xfe", 4))
127 _mm_fseek (modreader, 71, SEEK_SET);
128 if (!_mm_read_UBYTES (id, 4, modreader))
130 if (!memcmp (id, "GMFS", 4))
139 if (!(gdmbuf = (GDMNOTE *) _mm_malloc (32 * 64 * sizeof (GDMNOTE))))
141 if (!(mh = (GDMHEADER *) _mm_malloc (sizeof (GDMHEADER))))
155 GDM_ReadPattern (void)
157 int pos, flag, ch, i, maxch;
161 /* get pattern length */
162 length = _mm_read_I_UWORD (modreader) - 2;
164 /* clear pattern data */
165 memset (gdmbuf, 255, 32 * 64 * sizeof (GDMNOTE));
171 memset (&n, 255, sizeof (GDMNOTE));
172 flag = _mm_read_UBYTE (modreader);
175 if (_mm_eof (modreader))
177 _mm_errno = MMERR_LOADING_PATTERN;
194 n.note = _mm_read_UBYTE (modreader) & 127;
195 n.samp = _mm_read_UBYTE (modreader);
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);
210 memcpy (gdmbuf + (64U * ch) + pos, &n, sizeof (n));
217 GDM_ConvertTrack (GDMNOTE * tr)
223 for (t = 0; t < 64; t++)
228 if ((ins) && (ins != 255))
229 UniInstrument (ins - 1);
232 UniNote (((note >> 4) * OCTAVE) + (note & 0xf) - 1);
234 for (i = 0; i < 4; i++)
236 switch (tr[t].effect[i].effect)
238 case 1: /* toneslide up */
239 UniEffect (UNI_S3MEFFECTF, tr[t].effect[i].param);
241 case 2: /* toneslide down */
242 UniEffect (UNI_S3MEFFECTE, tr[t].effect[i].param);
244 case 3: /* glissando to note */
245 UniEffect (UNI_ITEFFECTG, tr[t].effect[i].param);
247 case 4: /* vibrato */
248 UniEffect (UNI_ITEFFECTH, tr[t].effect[i].param);
250 case 5: /* portamento+volslide */
251 UniEffect (UNI_ITEFFECTG, 0);
252 UniEffect (UNI_S3MEFFECTD, tr[t].effect[i].param);
254 case 6: /* vibrato+volslide */
255 UniEffect (UNI_ITEFFECTH, 0);
256 UniEffect (UNI_S3MEFFECTD, tr[t].effect[i].param);
258 case 7: /* tremolo */
259 UniEffect (UNI_S3MEFFECTR, tr[t].effect[i].param);
262 UniEffect (UNI_S3MEFFECTI, tr[t].effect[i].param);
265 UniPTEffect (0x09, tr[t].effect[i].param);
267 case 0x0a: /* volslide */
268 UniEffect (UNI_S3MEFFECTD, tr[t].effect[i].param);
270 case 0x0b: /* jump to order */
271 UniPTEffect (0x0b, tr[t].effect[i].param);
273 case 0x0c: /* volume set */
274 UniPTEffect (0x0c, tr[t].effect[i].param);
276 case 0x0d: /* pattern break */
277 UniPTEffect (0x0d, tr[t].effect[i].param);
279 case 0x0e: /* extended */
280 switch (tr[t].effect[i].param & 0xf0)
282 case 0x10: /* fine portamento up */
283 UniEffect (UNI_S3MEFFECTF,
284 0x0f | ((tr[t].effect[i].param << 4) & 0x0f));
286 case 0x20: /* fine portamento down */
287 UniEffect (UNI_S3MEFFECTE,
288 0xf0 | (tr[t].effect[i].param & 0x0f));
290 case 0x30: /* glissando control */
291 UniEffect (SS_GLISSANDO,
292 tr[t].effect[i].param & 0x0f);
294 case 0x40: /* vibrato waveform */
295 UniEffect (SS_VIBWAVE,
296 tr[t].effect[i].param & 0x0f);
298 case 0x50: /* set c4spd */
299 UniEffect (SS_FINETUNE,
300 tr[t].effect[i].param & 0x0f);
302 case 0x60: /* loop fun */
303 UniEffect (UNI_ITEFFECTS0,
304 (tr[t].effect[i].param & 0x0f) | 0xb0);
306 case 0x70: /* tremolo waveform */
307 UniEffect (SS_TREMWAVE,
308 tr[t].effect[i].param & 0x0f);
310 case 0x80: /* extra fine porta up */
311 UniEffect (UNI_S3MEFFECTF,
312 0x0e | ((tr[t].effect[i].param << 4) & 0x0f));
314 case 0x90: /* extra fine porta down */
315 UniEffect (UNI_S3MEFFECTE,
316 0xe0 | (tr[t].effect[i].param & 0x0f));
318 case 0xa0: /* fine volslide up */
319 UniEffect (UNI_S3MEFFECTD,
320 0x0f | ((tr[t].effect[i].param << 4) & 0x0f));
322 case 0xb0: /* fine volslide down */
323 UniEffect (UNI_S3MEFFECTE,
324 0xf0 | (tr[t].effect[i].param & 0x0f));
326 case 0xc0: /* note cut */
327 case 0xd0: /* note delay */
328 case 0xe0: /* extend row */
329 UniPTEffect (0xe, tr[t].effect[i].param);
333 case 0x0f: /* set tempo */
334 UniEffect (UNI_S3MEFFECTA, tr[t].effect[i].param);
336 case 0x10: /* arpeggio */
337 UniPTEffect (0x0, tr[t].effect[i].param);
339 case 0x12: /* retrigger */
340 UniEffect (UNI_S3MEFFECTQ, tr[t].effect[i].param);
342 case 0x13: /* set global volume */
343 UniEffect (UNI_XMEFFECTG, tr[t].effect[i].param);
345 case 0x14: /* fine vibrato */
346 UniEffect (UNI_ITEFFECTU, tr[t].effect[i].param);
348 case 0x1e: /* special */
349 switch (tr[t].effect[i].param & 0xf0)
351 case 8: /* set pan position */
352 if (tr[t].effect[i].param >= 128)
353 UniPTEffect (0x08, 255);
355 UniPTEffect (0x08, tr[t].effect[i].param << 1);
359 case 0x1f: /* set bpm */
360 if (tr[t].effect[i].param >= 0x20)
361 UniEffect (UNI_S3MEFFECTT, tr[t].effect[i].param);
371 GDM_Load (BOOL curious)
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);
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);
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);
410 /* have we ended abruptly? */
411 if (_mm_eof (modreader))
413 _mm_errno = MMERR_LOADING_HEADER;
418 if (mh->ordernum == 255)
420 _mm_errno = MMERR_LOADING_PATTERN;
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;
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;
438 /* read the order data */
439 if (!AllocPositions (mh->ordernum + 1))
441 _mm_errno = MMERR_OUT_OF_MEMORY;
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);
450 for (i = 0; i < mh->ordernum + 1; i++)
452 of.positions[of.numpos] = of.positions[i];
453 if (of.positions[i] < 254)
457 /* have we ended abruptly yet? */
458 if (_mm_eof (modreader))
460 _mm_errno = MMERR_LOADING_HEADER;
464 /* time to load the samples */
465 if (!AllocSamples ())
467 _mm_errno = MMERR_OUT_OF_MEMORY;
472 position = mh->samdata;
474 /* seek to instrument position */
475 _mm_fseek (modreader, mh->samhead, SEEK_SET);
477 for (i = 0; i < of.numins; i++)
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);
491 if (_mm_eof (modreader))
493 _mm_errno = MMERR_LOADING_SAMPLEINFO;
496 q->samplename = DupStr (s.sampname, 32, 0);
498 q->length = s.length;
499 q->loopstart = s.loopbeg;
500 q->loopend = s.loopend;
503 q->seekpos = position;
505 position += s.length;
510 q->flags |= SF_16BITS;
512 q->flags |= SF_STEREO;
516 /* set the panning */
517 for (i = x = 0; i < 32; i++)
519 of.panning[i] = mh->pantable[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)
532 of.panning[i] = PAN_CENTER;
533 if (mh->pantable[i] != 255)
539 of.numchn = 1; /* for broken counts */
541 /* load the pattern info */
542 of.numtrk = of.numpat * of.numchn;
544 /* jump to patterns */
545 _mm_fseek (modreader, mh->patternloc, SEEK_SET);
549 _mm_errno = MMERR_OUT_OF_MEMORY;
553 if (!AllocPatterns ())
555 _mm_errno = MMERR_OUT_OF_MEMORY;
559 for (i = track = 0; i < of.numpat; i++)
561 if (!GDM_ReadPattern ())
563 _mm_errno = MMERR_LOADING_PATTERN;
566 for (u = 0; u < of.numchn; u++, track++)
568 of.tracks[track] = GDM_ConvertTrack (&gdmbuf[u << 6]);
569 if (!of.tracks[track])
571 _mm_errno = MMERR_LOADING_TRACK;
584 _mm_fseek (modreader, 4, SEEK_SET);
585 if (!_mm_read_UBYTES (s, 32, modreader))
588 return DupStr (s, 28, 0);
595 "GDM (General DigiMusic)",