FS#12756 by Marek Salaba - update Czech translation
[maemo-rb.git] / apps / plugins / mikmod / load_mod.c
blob6075e9c7e1370a0543887f972e8b5e3c004a5f84
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
18 02111-1307, USA.
21 /*==============================================================================
23 $Id: load_mod.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
25 Generic MOD loader (Protracker, StarTracker, FastTracker, etc)
27 ==============================================================================*/
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
37 #include <ctype.h>
38 #include <stdio.h>
39 #ifdef HAVE_MEMORY_H
40 #include <memory.h>
41 #endif
42 #include <string.h>
44 #include "mikmod_internals.h"
46 #ifdef SUNOS
47 extern int fprintf(FILE *, const char *, ...);
48 #endif
50 /*========== Module structure */
52 typedef struct MSAMPINFO {
53 CHAR samplename[23]; /* 22 in module, 23 in memory */
54 UWORD length;
55 UBYTE finetune;
56 UBYTE volume;
57 UWORD reppos;
58 UWORD replen;
59 } MSAMPINFO;
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" */
68 } MODULEHEADER;
70 typedef struct MODTYPE {
71 CHAR id[5];
72 UBYTE channels;
73 CHAR *name;
74 } MODTYPE;
76 typedef struct MODNOTE {
77 UBYTE a, b, c, d;
78 } 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 int 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))) {
106 *descr = protracker;
107 modtype = 0;
108 *numchn = 4;
109 return 1;
112 /* Star Tracker */
113 if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) &&
114 (isdigit(id[3]))) {
115 *descr = startrekker;
116 modtype = trekker = 1;
117 *numchn = id[3] - '0';
118 if (*numchn == 4 || *numchn == 8)
119 return 1;
120 #ifdef MIKMOD_DEBUG
121 else
122 fprintf(stderr, "\rUnknown FLT%d module type\n", *numchn);
123 #endif
124 return 0;
127 /* Oktalyzer (Amiga) */
128 if (!memcmp(id, "OKTA", 4)) {
129 *descr = oktalyzer;
130 modtype = 1;
131 *numchn = 8;
132 return 1;
135 /* Oktalyser (Atari) */
136 if (!memcmp(id, "CD81", 4)) {
137 *descr = oktalyser;
138 modtype = 1;
139 *numchn = 8;
140 return 1;
143 /* Fasttracker */
144 if ((!memcmp(id + 1, "CHN", 3)) && (isdigit(id[0]))) {
145 *descr = fasttracker;
146 modtype = 1;
147 *numchn = id[0] - '0';
148 return 1;
150 /* Fasttracker or Taketracker */
151 if (((!memcmp(id + 2, "CH", 2)) || (!memcmp(id + 2, "CN", 2)))
152 && (isdigit(id[0])) && (isdigit(id[1]))) {
153 if (id[3] == 'H') {
154 *descr = fasttracker;
155 modtype = 2; /* this can also be Imago Orpheus */
156 } else {
157 *descr = taketracker;
158 modtype = 1;
160 *numchn = (id[0] - '0') * 10 + (id[1] - '0');
161 return 1;
164 return 0;
167 static int MOD_Test(void)
169 UBYTE id[4], numchn;
170 CHAR *descr;
172 _mm_fseek(modreader, MODULEHEADERSIZE, SEEK_SET);
173 if (!_mm_read_UBYTES(id, 4, modreader))
174 return 0;
176 if (MOD_CheckType(id, &numchn, &descr))
177 return 1;
179 return 0;
182 static int MOD_Init(void)
184 if (!(mh = (MODULEHEADER *)MikMod_malloc(sizeof(MODULEHEADER))))
185 return 0;
186 return 1;
189 static void MOD_Cleanup(void)
191 MikMod_free(mh);
192 MikMod_free(patbuf);
196 Old (amiga) noteinfo:
198 _____byte 1_____ byte2_ _____byte 3_____ byte4_
199 / \ / \ / \ / \
200 0000 0000-00000000 0000 0000-00000000
202 Upper four 12 bits for Lower four Effect command.
203 bits of sam- note period. bits of sam-
204 ple number. ple number.
208 static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
210 UBYTE instrument, effect, effdat, note;
211 UWORD period;
212 UBYTE lastnote = 0;
214 /* extract the various information from the 4 bytes that make up a note */
215 instrument = (n->a & 0x10) | (n->c >> 4);
216 period = (((UWORD)n->a & 0xf) << 8) + n->b;
217 effect = n->c & 0xf;
218 effdat = n->d;
220 /* Convert the period to a note number */
221 note = 0;
222 if (period) {
223 for (note = 0; note < 7 * OCTAVE; note++)
224 if (period >= npertab[note])
225 break;
226 if (note == 7 * OCTAVE)
227 note = 0;
228 else
229 note++;
232 if (instrument) {
233 /* if instrument does not exist, note cut */
234 if ((instrument > 31) || (!mh->samples[instrument - 1].length)) {
235 UniPTEffect(0xc, 0);
236 if (effect == 0xc)
237 effect = effdat = 0;
238 } else {
239 /* Protracker handling */
240 if (!modtype) {
241 /* if we had a note, then change instrument... */
242 if (note)
243 UniInstrument(instrument - 1);
244 /* ...otherwise, only adjust volume... */
245 else {
246 /* ...unless an effect was specified, which forces a new
247 note to be played */
248 if (effect || effdat) {
249 UniInstrument(instrument - 1);
250 note = lastnote;
251 } else
252 UniPTEffect(0xc,
253 mh->samples[instrument -
254 1].volume & 0x7f);
256 } else {
257 /* Fasttracker handling */
258 UniInstrument(instrument - 1);
259 if (!note)
260 note = lastnote;
264 if (note) {
265 UniNote(note + 2 * OCTAVE - 1);
266 lastnote = note;
269 /* Convert pattern jump from Dec to Hex */
270 if (effect == 0xd)
271 effdat = (((effdat & 0xf0) >> 4) * 10) + (effdat & 0xf);
273 /* Volume slide, up has priority */
274 if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0))
275 effdat &= 0xf0;
277 /* Handle ``heavy'' volumes correctly */
278 if ((effect == 0xc) && (effdat > 0x40))
279 effdat = 0x40;
281 /* An isolated 100, 200 or 300 effect should be ignored (no
282 "standalone" porta memory in mod files). However, a sequence such
283 as 1XX, 100, 100, 100 is fine. */
284 if ((!effdat) && ((effect == 1)||(effect == 2)||(effect ==3)) &&
285 (lasteffect < 0x10) && (effect != lasteffect))
286 effect = 0;
288 UniPTEffect(effect, effdat);
289 if (effect == 8)
290 of.flags |= UF_PANNING;
292 return effect;
295 static UBYTE *ConvertTrack(MODNOTE *n, int numchn)
297 int t;
298 UBYTE lasteffect = 0x10; /* non existant effect */
300 UniReset();
301 for (t = 0; t < 64; t++) {
302 lasteffect = ConvertNote(n,lasteffect);
303 UniNewline();
304 n += numchn;
306 return UniDup();
309 /* Loads all patterns of a modfile and converts them into the 3 byte format. */
310 static int ML_LoadPatterns(void)
312 int t, tracks = 0;
313 unsigned int s;
315 if (!AllocPatterns())
316 return 0;
317 if (!AllocTracks())
318 return 0;
320 /* Allocate temporary buffer for loading and converting the patterns */
321 if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
322 return 0;
324 if (trekker && of.numchn == 8) {
325 /* Startrekker module dual pattern */
326 for (t = 0; t < of.numpat; t++) {
327 for (s = 0; s < (64U * 4); s++) {
328 patbuf[s].a = _mm_read_UBYTE(modreader);
329 patbuf[s].b = _mm_read_UBYTE(modreader);
330 patbuf[s].c = _mm_read_UBYTE(modreader);
331 patbuf[s].d = _mm_read_UBYTE(modreader);
333 for (s = 0; s < 4; s++)
334 if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
335 return 0;
336 for (s = 0; s < (64U * 4); s++) {
337 patbuf[s].a = _mm_read_UBYTE(modreader);
338 patbuf[s].b = _mm_read_UBYTE(modreader);
339 patbuf[s].c = _mm_read_UBYTE(modreader);
340 patbuf[s].d = _mm_read_UBYTE(modreader);
342 for (s = 0; s < 4; s++)
343 if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
344 return 0;
346 } else {
347 /* Generic module pattern */
348 for (t = 0; t < of.numpat; t++) {
349 /* Load the pattern into the temp buffer and convert it */
350 for (s = 0; s < (64U * of.numchn); s++) {
351 patbuf[s].a = _mm_read_UBYTE(modreader);
352 patbuf[s].b = _mm_read_UBYTE(modreader);
353 patbuf[s].c = _mm_read_UBYTE(modreader);
354 patbuf[s].d = _mm_read_UBYTE(modreader);
356 for (s = 0; s < of.numchn; s++)
357 if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, of.numchn)))
358 return 0;
361 return 1;
364 static int MOD_Load(int curious)
366 int t, scan;
367 SAMPLE *q;
368 MSAMPINFO *s;
369 CHAR *descr;
371 /* try to read module header */
372 _mm_read_string((CHAR *)mh->songname, 20, modreader);
373 mh->songname[20] = 0; /* just in case */
375 for (t = 0; t < 31; t++) {
376 s = &mh->samples[t];
377 _mm_read_string(s->samplename, 22, modreader);
378 s->samplename[22] = 0; /* just in case */
379 s->length = _mm_read_M_UWORD(modreader);
380 s->finetune = _mm_read_UBYTE(modreader);
381 s->volume = _mm_read_UBYTE(modreader);
382 s->reppos = _mm_read_M_UWORD(modreader);
383 s->replen = _mm_read_M_UWORD(modreader);
386 mh->songlength = _mm_read_UBYTE(modreader);
388 /* this fixes mods which declare more than 128 positions.
389 * eg: beatwave.mod */
390 if (mh->songlength > 128) { mh->songlength = 128; }
392 mh->magic1 = _mm_read_UBYTE(modreader);
393 _mm_read_UBYTES(mh->positions, 128, modreader);
394 _mm_read_UBYTES(mh->magic2, 4, modreader);
396 if (_mm_eof(modreader)) {
397 _mm_errno = MMERR_LOADING_HEADER;
398 return 0;
401 /* set module variables */
402 of.initspeed = 6;
403 of.inittempo = 125;
404 if (!(MOD_CheckType(mh->magic2, &of.numchn, &descr))) {
405 _mm_errno = MMERR_NOT_A_MODULE;
406 return 0;
408 if (trekker && of.numchn == 8)
409 for (t = 0; t < 128; t++)
410 /* if module pretends to be FLT8, yet the order table
411 contains odd numbers, chances are it's a lying FLT4... */
412 if (mh->positions[t] & 1) {
413 of.numchn = 4;
414 break;
416 if (trekker && of.numchn == 8)
417 for (t = 0; t < 128; t++)
418 mh->positions[t] >>= 1;
420 of.songname = DupStr(mh->songname, 21, 1);
421 of.numpos = mh->songlength;
422 of.reppos = 0;
424 /* Count the number of patterns */
425 of.numpat = 0;
426 for (t = 0; t < of.numpos; t++)
427 if (mh->positions[t] > of.numpat)
428 of.numpat = mh->positions[t];
430 /* since some old modules embed extra patterns, we have to check the
431 whole list to get the samples' file offsets right - however we can find
432 garbage here, so check carefully */
433 scan = 1;
434 for (t = of.numpos; t < 128; t++)
435 if (mh->positions[t] >= 0x80)
436 scan = 0;
437 if (scan)
438 for (t = of.numpos; t < 128; t++) {
439 if (mh->positions[t] > of.numpat)
440 of.numpat = mh->positions[t];
441 if ((curious) && (mh->positions[t]))
442 of.numpos = t + 1;
444 of.numpat++;
445 of.numtrk = of.numpat * of.numchn;
447 if (!AllocPositions(of.numpos))
448 return 0;
449 for (t = 0; t < of.numpos; t++)
450 of.positions[t] = mh->positions[t];
452 /* Finally, init the sampleinfo structures */
453 of.numins = of.numsmp = 31;
454 if (!AllocSamples())
455 return 0;
456 s = mh->samples;
457 q = of.samples;
458 for (t = 0; t < of.numins; t++) {
459 /* convert the samplename */
460 q->samplename = DupStr(s->samplename, 23, 1);
461 /* init the sampleinfo variables and convert the size pointers */
462 q->speed = finetune[s->finetune & 0xf];
463 q->volume = s->volume & 0x7f;
464 q->loopstart = (ULONG)s->reppos << 1;
465 q->loopend = q->loopstart + ((ULONG)s->replen << 1);
466 q->length = (ULONG)s->length << 1;
467 q->flags = SF_SIGNED;
468 /* Imago Orpheus creates MODs with 16 bit samples, check */
469 if ((modtype == 2) && (s->volume & 0x80)) {
470 q->flags |= SF_16BITS;
471 descr = orpheus;
473 if (s->replen > 2)
474 q->flags |= SF_LOOP;
476 s++;
477 q++;
480 of.modtype = StrDup(descr);
482 if (!ML_LoadPatterns())
483 return 0;
485 return 1;
488 static CHAR *MOD_LoadTitle(void)
490 CHAR s[21];
492 _mm_fseek(modreader, 0, SEEK_SET);
493 if (!_mm_read_UBYTES(s, 20, modreader))
494 return NULL;
495 s[20] = 0; /* just in case */
497 return (DupStr(s, 21, 1));
500 /*========== Loader information */
502 MIKMODAPI MLOADER load_mod = {
503 NULL,
504 "Standard module",
505 "MOD (31 instruments)",
506 MOD_Init,
507 MOD_Test,
508 MOD_Load,
509 MOD_Cleanup,
510 MOD_LoadTitle
513 /* ex:set ts=4: */