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 /*==============================================================================
25 Generic MOD loader (Protracker, StarTracker, FastTracker, etc)
27 ==============================================================================*/
43 #include "mikmod_internals.h"
44 #include "mikmod_ctype.h"
47 extern int fprintf(FILE *, const char *, ...);
50 /*========== Module structure */
52 typedef struct MSAMPINFO {
53 CHAR samplename[23]; /* 22 in module, 23 in memory */
61 typedef struct MODULEHEADER {
62 CHAR songname[21]; /* the songname.. 20 in module, 21 in memory */
63 MSAMPINFO samples[31]; /* all sampleinfo */
64 UBYTE songlength; /* number of patterns used */
65 UBYTE magic1; /* should be 127 */
66 UBYTE positions[128]; /* which pattern to play at pos */
67 UBYTE magic2[4]; /* string "M.K." or "FLT4" or "FLT8" */
70 typedef struct MODTYPE {
76 typedef struct MODNOTE {
80 /*========== Loader variables */
82 #define MODULEHEADERSIZE 0x438
84 static CHAR protracker[] = "Protracker";
85 static CHAR startrekker[] = "Startrekker";
86 static CHAR fasttracker[] = "Fasttracker";
87 static CHAR oktalyser[] = "Oktalyser";
88 static CHAR oktalyzer[] = "Oktalyzer";
89 static CHAR taketracker[] = "TakeTracker";
90 static CHAR orpheus[] = "Imago Orpheus (MOD format)";
92 static MODULEHEADER *mh = NULL;
93 static MODNOTE *patbuf = NULL;
94 static int modtype, trekker;
96 /*========== Loader code */
98 /* given the module ID, determine the number of channels and the tracker
99 description ; also alters modtype */
100 static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
102 modtype = trekker = 0;
104 /* Protracker and variants */
105 if ((!memcmp(id, "M.K.", 4)) || (!memcmp(id, "M!K!", 4))) {
113 if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) &&
114 (mik_isdigit(id[3]))) {
115 *descr = startrekker;
116 modtype = trekker = 1;
117 *numchn = id[3] - '0';
118 if (*numchn == 4 || *numchn == 8)
122 fprintf(stderr, "\rUnknown FLT%d module type\n", *numchn);
127 /* Oktalyzer (Amiga) */
128 if (!memcmp(id, "OKTA", 4)) {
135 /* Oktalyser (Atari) */
136 if (!memcmp(id, "CD81", 4)) {
144 if ((!memcmp(id + 1, "CHN", 3)) && (mik_isdigit(id[0]))) {
145 *descr = fasttracker;
147 *numchn = id[0] - '0';
150 /* Fasttracker or Taketracker */
151 if (((!memcmp(id + 2, "CH", 2)) || (!memcmp(id + 2, "CN", 2)))
152 && (mik_isdigit(id[0])) && (mik_isdigit(id[1]))) {
154 *descr = fasttracker;
155 modtype = 2; /* this can also be Imago Orpheus */
157 *descr = taketracker;
160 *numchn = (id[0] - '0') * 10 + (id[1] - '0');
167 static BOOL MOD_Test(void)
172 _mm_fseek(modreader, MODULEHEADERSIZE, SEEK_SET);
173 if (!_mm_read_UBYTES(id, 4, modreader))
176 if (MOD_CheckType(id, &numchn, &descr))
182 static BOOL MOD_Init(void)
184 if (!(mh = (MODULEHEADER *)MikMod_malloc(sizeof(MODULEHEADER))))
189 static void MOD_Cleanup(void)
198 Old (amiga) noteinfo:
200 _____byte 1_____ byte2_ _____byte 3_____ byte4_
202 0000 0000-00000000 0000 0000-00000000
204 Upper four 12 bits for Lower four Effect command.
205 bits of sam- note period. bits of sam-
206 ple number. ple number.
210 static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
212 UBYTE instrument, effect, effdat, note;
216 /* extract the various information from the 4 bytes that make up a note */
217 instrument = (n->a & 0x10) | (n->c >> 4);
218 period = (((UWORD)n->a & 0xf) << 8) + n->b;
222 /* Convert the period to a note number */
225 for (note = 0; note < 7 * OCTAVE; note++)
226 if (period >= npertab[note])
228 if (note == 7 * OCTAVE)
235 /* if instrument does not exist, note cut */
236 if ((instrument > 31) || (!mh->samples[instrument - 1].length)) {
241 /* Protracker handling */
243 /* if we had a note, then change instrument... */
245 UniInstrument(instrument - 1);
246 /* ...otherwise, only adjust volume... */
248 /* ...unless an effect was specified, which forces a new
250 if (effect || effdat) {
251 UniInstrument(instrument - 1);
255 mh->samples[instrument -
259 /* Fasttracker handling */
260 UniInstrument(instrument - 1);
267 UniNote(note + 2 * OCTAVE - 1);
271 /* Convert pattern jump from Dec to Hex */
273 effdat = (((effdat & 0xf0) >> 4) * 10) + (effdat & 0xf);
275 /* Volume slide, up has priority */
276 if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0))
279 /* Handle ``heavy'' volumes correctly */
280 if ((effect == 0xc) && (effdat > 0x40))
283 /* An isolated 100, 200 or 300 effect should be ignored (no
284 "standalone" porta memory in mod files). However, a sequence such
285 as 1XX, 100, 100, 100 is fine. */
286 if ((!effdat) && ((effect == 1)||(effect == 2)||(effect ==3)) &&
287 (lasteffect < 0x10) && (effect != lasteffect))
290 UniPTEffect(effect, effdat);
292 of.flags |= UF_PANNING;
297 static UBYTE *ConvertTrack(MODNOTE *n, int numchn)
300 UBYTE lasteffect = 0x10; /* non existant effect */
303 for (t = 0; t < 64; t++) {
304 lasteffect = ConvertNote(n,lasteffect);
311 /* Loads all patterns of a modfile and converts them into the 3 byte format. */
312 static BOOL ML_LoadPatterns(void)
314 int t, s, tracks = 0;
316 if (!AllocPatterns())
321 /* Allocate temporary buffer for loading and converting the patterns */
322 if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
325 if (trekker && of.numchn == 8) {
326 /* Startrekker module dual pattern */
327 for (t = 0; t < of.numpat; t++) {
328 for (s = 0; s < (64U * 4); s++) {
329 patbuf[s].a = _mm_read_UBYTE(modreader);
330 patbuf[s].b = _mm_read_UBYTE(modreader);
331 patbuf[s].c = _mm_read_UBYTE(modreader);
332 patbuf[s].d = _mm_read_UBYTE(modreader);
334 for (s = 0; s < 4; s++)
335 if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
337 for (s = 0; s < (64U * 4); s++) {
338 patbuf[s].a = _mm_read_UBYTE(modreader);
339 patbuf[s].b = _mm_read_UBYTE(modreader);
340 patbuf[s].c = _mm_read_UBYTE(modreader);
341 patbuf[s].d = _mm_read_UBYTE(modreader);
343 for (s = 0; s < 4; s++)
344 if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
348 /* Generic module pattern */
349 for (t = 0; t < of.numpat; t++) {
350 /* Load the pattern into the temp buffer and convert it */
351 for (s = 0; s < (int)(64U * of.numchn); s++) {
352 patbuf[s].a = _mm_read_UBYTE(modreader);
353 patbuf[s].b = _mm_read_UBYTE(modreader);
354 patbuf[s].c = _mm_read_UBYTE(modreader);
355 patbuf[s].d = _mm_read_UBYTE(modreader);
357 for (s = 0; s < of.numchn; s++)
358 if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, of.numchn)))
365 static BOOL MOD_Load(BOOL curious)
372 /* try to read module header */
373 _mm_read_string((CHAR *)mh->songname, 20, modreader);
374 mh->songname[20] = 0; /* just in case */
376 for (t = 0; t < 31; t++) {
378 _mm_read_string(s->samplename, 22, modreader);
379 s->samplename[22] = 0; /* just in case */
380 s->length = _mm_read_M_UWORD(modreader);
381 s->finetune = _mm_read_UBYTE(modreader);
382 s->volume = _mm_read_UBYTE(modreader);
383 s->reppos = _mm_read_M_UWORD(modreader);
384 s->replen = _mm_read_M_UWORD(modreader);
387 mh->songlength = _mm_read_UBYTE(modreader);
389 /* this fixes mods which declare more than 128 positions.
390 * eg: beatwave.mod */
391 if (mh->songlength > 128) { mh->songlength = 128; }
393 mh->magic1 = _mm_read_UBYTE(modreader);
394 _mm_read_UBYTES(mh->positions, 128, modreader);
395 _mm_read_UBYTES(mh->magic2, 4, modreader);
397 if (_mm_eof(modreader)) {
398 _mm_errno = MMERR_LOADING_HEADER;
402 /* set module variables */
405 if (!(MOD_CheckType(mh->magic2, &of.numchn, &descr))) {
406 _mm_errno = MMERR_NOT_A_MODULE;
409 if (trekker && of.numchn == 8)
410 for (t = 0; t < 128; t++)
411 /* if module pretends to be FLT8, yet the order table
412 contains odd numbers, chances are it's a lying FLT4... */
413 if (mh->positions[t] & 1) {
417 if (trekker && of.numchn == 8)
418 for (t = 0; t < 128; t++)
419 mh->positions[t] >>= 1;
421 of.songname = DupStr(mh->songname, 21, 1);
422 of.numpos = mh->songlength;
425 /* Count the number of patterns */
427 for (t = 0; t < of.numpos; t++)
428 if (mh->positions[t] > of.numpat)
429 of.numpat = mh->positions[t];
431 /* since some old modules embed extra patterns, we have to check the
432 whole list to get the samples' file offsets right - however we can find
433 garbage here, so check carefully */
435 for (t = of.numpos; t < 128; t++)
436 if (mh->positions[t] >= 0x80)
439 for (t = of.numpos; t < 128; t++) {
440 if (mh->positions[t] > of.numpat)
441 of.numpat = mh->positions[t];
442 if ((curious) && (mh->positions[t]))
446 of.numtrk = of.numpat * of.numchn;
448 if (!AllocPositions(of.numpos))
450 for (t = 0; t < of.numpos; t++)
451 of.positions[t] = mh->positions[t];
453 /* Finally, init the sampleinfo structures */
454 of.numins = of.numsmp = 31;
459 for (t = 0; t < of.numins; t++) {
460 /* convert the samplename */
461 q->samplename = DupStr(s->samplename, 23, 1);
462 /* init the sampleinfo variables and convert the size pointers */
463 q->speed = finetune[s->finetune & 0xf];
464 q->volume = s->volume & 0x7f;
465 q->loopstart = (ULONG)s->reppos << 1;
466 q->loopend = q->loopstart + ((ULONG)s->replen << 1);
467 q->length = (ULONG)s->length << 1;
468 q->flags = SF_SIGNED;
469 /* Imago Orpheus creates MODs with 16 bit samples, check */
470 if ((modtype == 2) && (s->volume & 0x80)) {
471 q->flags |= SF_16BITS;
481 of.modtype = MikMod_strdup(descr);
483 if (!ML_LoadPatterns())
489 static CHAR *MOD_LoadTitle(void)
493 _mm_fseek(modreader, 0, SEEK_SET);
494 if (!_mm_read_UBYTES(s, 20, modreader))
496 s[20] = 0; /* just in case */
498 return (DupStr(s, 21, 1));
501 /*========== Loader information */
503 MIKMODAPI MLOADER load_mod = {
506 "MOD (31 instruments)",