/* Extended Module Player * Copyright (C) 1996-1999 Claudio Matsuoka and Hipolito Carraro Jr * * This file is part of the Extended Module Player and is distributed * under the terms of the GNU General Public License. See doc/COPYING * for more information. */ /* INCOMPLETE LOADER!!! NO EFFECTS! */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "load.h" struct fnk_instrument { uint8 name[19]; /* ASCIIZ instrument name */ uint32 loop_start; /* Instrument loop start */ uint32 length; /* Instrument length */ uint8 volume; /* Volume (0-255) */ uint8 pan; /* Pan (0-255) */ uint8 shifter; /* Portamento and offset shift */ uint8 wavsallorm; /* Vibrato and tremolo wavsallorms */ uint8 retrig; /* Retrig and arpeggio speed */ } PACKED; struct fnk_header { uint8 marker[4]; /* 'Funk' */ uint8 info[4]; /* */ uint32 filesize; /* File size */ uint8 format[4]; /* F2xx, Fkxx or Fvxx */ uint8 loop; /* Loop order number */ uint8 order[256]; /* Order list */ uint8 pbrk[128]; /* Break list for patterns */ struct fnk_instrument fih[64]; /* Instruments */ } PACKED; #if 0 #define FX_NONE 0xff static uint8 fx[] = { FX_NONE, FX_NONE, FX_NONE, FX_NONE, FX_NONE, FX_NONE, FX_NONE, FX_NONE, FX_NONE, FX_NONE, FX_PORTA_UP, FX_PORTA_DN, FX_TONEPORTA, FX_EXTENDED, FX_VIBRATO, FX_NONE, FX_NONE, FX_NONE, }; #endif int fnk_load (FILE * f) { int i, j; struct xxm_event *event; struct fnk_header ffh; uint8 ev[3]; LOAD_INIT (); fread (&ffh, 1, sizeof (ffh), f); if (strncmp ((char *) ffh.marker, "Funk", 4) || strncmp ((char *) ffh.format, "F2", 2)) return -1; xxh->chn = (ffh.format[2] < '0') || (ffh.format[2] > '9') || (ffh.format[3] < '0') || (ffh.format[3] > '9') ? 8 : (ffh.format[2] - '0') * 10 + ffh.format[3] - '0'; xxh->ins = 64; for (i = 0; i < 256 && ffh.order[i] != 0xff; i++) if (ffh.order[i] > xxh->pat) xxh->pat = i; xxh->len = i; xxh->trk = xxh->chn * xxh->pat; memcpy (xxo, ffh.order, xxh->len); xxh->tpo = 6; xxh->bpm = ffh.info[3] >> 1; if (xxh->bpm & 64) xxh->bpm = -(xxh->bpm & 63); xxh->bpm += 125; xxh->smp = xxh->ins; strcpy (xmp_ctl->type, "Funktracker"); MODULE_INFO (); INSTRUMENT_INIT (); /* Convert instruments */ for (i = 0; i < xxh->ins; i++) { xxi[i] = calloc (sizeof (struct xxm_instrument), 1); L_ENDIAN32 (ffh.fih[i].length); L_ENDIAN32 (ffh.fih[i].loop_start); xxih[i].nsm = !!(xxs[i].len = ffh.fih[i].length); xxs[i].lps = ffh.fih[i].loop_start; if (xxs[i].lps == -1) xxs[i].lps = 0; xxs[i].lpe = ffh.fih[i].length; xxs[i].flg = ffh.fih[i].loop_start != -1 ? WAVE_LOOPING : 0; xxi[i][0].vol = ffh.fih[i].volume; xxi[i][0].pan = ffh.fih[i].pan; xxi[i][0].sid = i; strncpy ((char *) xxih[i].name, ffh.fih[i].name, 19); str_adj ((char *) xxih[i].name); if ((V (1)) && (strlen ((char *) xxih[i].name) || (xxs[i].len > 2))) report ("[%2X] %-20.20s %04x %04x %04x %c V%02x P%02x\n", i, xxih[i].name, xxs[i].len, xxs[i].lps, xxs[i].lpe, xxs[i].flg & WAVE_LOOPING ? 'L' : ' ', xxi[i][0].vol, xxi[i][0].pan); } PATTERN_INIT (); /* Read and convert patterns */ if (V (0)) report ("Stored patterns: %d ", xxh->pat); for (i = 0; i < xxh->pat; i++) { PATTERN_ALLOC (i); xxp[i]->rows = 64; TRACK_ALLOC (i); EVENT (i, 1, ffh.pbrk[i]).f2t = FX_BREAK; for (j = 0; j < 64 * xxh->chn; j++) { event = &EVENT (i, j % xxh->chn, j / xxh->chn); fread (&ev, 1, 3, f); switch (ev[0] >> 2) { case 0x3f: case 0x3e: case 0x3d: break; default: event->note = 25 + (ev[0] >> 2); event->ins = 1 + MSN (ev[1]) + ((ev[0] & 0x03) << 4); event->vol = ffh.fih[event->ins - 1].volume; } #if 0 if (ev[2] + 1) { event->fxt = fx[MSN (ev[2])]; event->fxp = fx[LSN (ev[2])]; if (!event->fxp) event->fxp = 0; switch (event->fxt) { case FX_ARPEGGIO: event->fxp = 0; break; case FX_VIBRATO: event->fxp |= 0x80; /* Wild guess */ break; case FX_EXTENDED: event->fxp = 0x53; /* Wild guess */ break; } } #endif } if (V (0)) report ("."); } /* Read samples */ if (V (0)) report ("\nStored samples : %d ", xxh->smp); for (i = 0; i < xxh->ins; i++) { if (xxs[i].len <= 2) continue; xmp_drv_loadpatch (f, xxi[i][0].sid, xmp_ctl->c4rate, 0, &xxs[i], NULL); if (V (0)) report ("."); } if (V (0)) report ("\n"); for (i = 0; i < xxh->chn; i++) xxc[i].pan = (i % 2) * 0xff; xmp_ctl->volbase = 0x100; return 0; }