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 /*==============================================================================
23 $Id: load_far.c,v 1.29 1999/10/25 16:31:41 miod Exp $
25 Farandole (FAR) module loader
27 ==============================================================================*/
35 #include "unimod_priv.h"
37 /*========== Module structure */
39 typedef struct FARHEADER1
41 UBYTE id[4]; /* file magic */
42 CHAR songname[40]; /* songname */
43 CHAR blah[3]; /* 13,10,26 */
44 UWORD headerlen; /* remaining length of header in bytes */
55 typedef struct FARHEADER2
65 typedef struct FARSAMPLE
78 typedef struct FARNOTE
80 UBYTE note, ins, vol, eff;
84 /*========== Loader variables */
86 static CHAR FAR_Version[] = "Farandole";
87 static FARHEADER1 *mh1 = NULL;
88 static FARHEADER2 *mh2 = NULL;
89 static FARNOTE *pat = NULL;
91 static unsigned char FARSIG[4 + 3] =
92 {'F', 'A', 'R', 0xfe, 13, 10, 26};
94 /*========== Loader code */
101 if (!_mm_read_UBYTES (id, 47, modreader))
103 if ((memcmp (id, FARSIG, 4)) || (memcmp (id + 44, FARSIG + 4, 3)))
111 if (!(mh1 = (FARHEADER1 *) _mm_malloc (sizeof (FARHEADER1))))
113 if (!(mh2 = (FARHEADER2 *) _mm_malloc (sizeof (FARHEADER2))))
115 if (!(pat = (FARNOTE *) _mm_malloc (256 * 16 * 4 * sizeof (FARNOTE))))
130 FAR_ConvertTrack (FARNOTE * n, int rows)
135 for (t = 0; t < rows; t++)
139 UniInstrument (n->ins);
140 UniNote (n->note + 3 * OCTAVE - 1);
143 UniPTEffect (0xc, (n->vol & 0xf) << 2);
147 case 0x3: /* porta to note */
148 UniPTEffect (0x3, (n->eff & 0xf) << 4);
150 case 0x5: /* set vibrato depth */
151 vibdepth = n->eff & 0xf;
153 case 0x6: /* vibrato */
154 UniPTEffect (0x4, ((n->eff & 0xf) << 4) | vibdepth);
156 case 0x7: /* volume slide up */
157 UniPTEffect (0xa, (n->eff & 0xf) << 4);
159 case 0x8: /* volume slide down */
160 UniPTEffect (0xa, n->eff & 0xf);
162 case 0xf: /* set speed */
163 UniPTEffect (0xf, n->eff & 0xf);
166 /* others not yet implemented */
169 fprintf (stderr, "\rFAR: unsupported effect %02X\n", n->eff);
181 FAR_Load (BOOL curious)
183 int t, u, tracks = 0;
189 /* try to read module header (first part) */
190 _mm_read_UBYTES (mh1->id, 4, modreader);
191 _mm_read_SBYTES (mh1->songname, 40, modreader);
192 _mm_read_SBYTES (mh1->blah, 3, modreader);
193 mh1->headerlen = _mm_read_I_UWORD (modreader);
194 mh1->version = _mm_read_UBYTE (modreader);
195 _mm_read_UBYTES (mh1->onoff, 16, modreader);
196 _mm_read_UBYTES (mh1->edit1, 9, modreader);
197 mh1->speed = _mm_read_UBYTE (modreader);
198 _mm_read_UBYTES (mh1->panning, 16, modreader);
199 _mm_read_UBYTES (mh1->edit2, 4, modreader);
200 mh1->stlen = _mm_read_I_UWORD (modreader);
202 /* init modfile data */
203 of.modtype = strdup (FAR_Version);
204 of.songname = DupStr (mh1->songname, 40, 1);
206 of.initspeed = mh1->speed;
209 for (t = 0; t < 16; t++)
210 of.panning[t] = mh1->panning[t] << 4;
212 /* read songtext into comment field */
214 if (!ReadComment (mh1->stlen))
217 /* try to read module header (second part) */
218 _mm_read_UBYTES (mh2->orders, 256, modreader);
219 mh2->numpat = _mm_read_UBYTE (modreader);
220 mh2->snglen = _mm_read_UBYTE (modreader);
221 mh2->loopto = _mm_read_UBYTE (modreader);
222 _mm_read_I_UWORDS (mh2->patsiz, 256, modreader);
224 of.numpos = mh2->snglen;
225 if (!AllocPositions (of.numpos))
227 for (t = 0; t < of.numpos; t++)
229 if (mh2->orders[t] == 0xff)
231 of.positions[t] = mh2->orders[t];
234 /* count number of patterns stored in file */
236 for (t = 0; t < 256; t++)
238 if ((t + 1) > of.numpat)
240 of.numtrk = of.numpat * of.numchn;
242 /* seek across eventual new data */
243 _mm_fseek (modreader, mh1->headerlen - (869 + mh1->stlen), SEEK_CUR);
245 /* alloc track and pattern structures */
248 if (!AllocPatterns ())
251 for (t = 0; t < of.numpat; t++)
253 UBYTE rows = 0, tempo;
255 memset (pat, 0, 256 * 16 * 4 * sizeof (FARNOTE));
258 rows = _mm_read_UBYTE (modreader);
259 tempo = _mm_read_UBYTE (modreader);
262 /* file often allocates 64 rows even if there are less in pattern */
263 if (mh2->patsiz[t] < 2 + (rows * 16 * 4))
265 _mm_errno = MMERR_LOADING_PATTERN;
268 for (u = (mh2->patsiz[t] - 2) / 4; u; u--, crow++)
270 crow->note = _mm_read_UBYTE (modreader);
271 crow->ins = _mm_read_UBYTE (modreader);
272 crow->vol = _mm_read_UBYTE (modreader);
273 crow->eff = _mm_read_UBYTE (modreader);
276 if (_mm_eof (modreader))
278 _mm_errno = MMERR_LOADING_PATTERN;
283 of.pattrows[t] = rows;
284 for (u = 16; u; u--, crow++)
285 if (!(of.tracks[tracks++] = FAR_ConvertTrack (crow, rows)))
287 _mm_errno = MMERR_LOADING_PATTERN;
295 /* read sample map */
296 if (!_mm_read_UBYTES (smap, 8, modreader))
298 _mm_errno = MMERR_LOADING_HEADER;
302 /* count number of samples used */
304 for (t = 0; t < 64; t++)
305 if (smap[t >> 3] & (1 << (t & 7)))
307 of.numsmp = of.numins;
309 /* alloc sample structs */
310 if (!AllocSamples ())
314 for (t = 0; t < of.numsmp; t++)
317 q->flags = SF_SIGNED;
318 if (smap[t >> 3] & (1 << (t & 7)))
320 _mm_read_SBYTES (s.samplename, 32, modreader);
321 s.length = _mm_read_I_ULONG (modreader);
322 s.finetune = _mm_read_UBYTE (modreader);
323 s.volume = _mm_read_UBYTE (modreader);
324 s.reppos = _mm_read_I_ULONG (modreader);
325 s.repend = _mm_read_I_ULONG (modreader);
326 s.type = _mm_read_UBYTE (modreader);
327 s.loop = _mm_read_UBYTE (modreader);
329 q->samplename = DupStr (s.samplename, 32, 1);
330 q->length = s.length;
331 q->loopstart = s.reppos;
332 q->loopend = s.repend;
333 q->volume = s.volume << 2;
336 q->flags |= SF_16BITS;
340 q->seekpos = _mm_ftell (modreader);
341 _mm_fseek (modreader, q->length, SEEK_CUR);
344 q->samplename = DupStr (NULL, 0, 0);
355 _mm_fseek (modreader, 4, SEEK_SET);
356 if (!_mm_read_UBYTES (s, 40, modreader))
359 return (DupStr (s, 40, 1));
362 /*========== Loader information */
368 "FAR (Farandole Composer)",