static void get_smpl(struct xmp_context *ctx, int size, FILE *f) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; int i, flags; reportv(ctx, 0, "Stored samples : %d ", m->xxh->smp); reportv(ctx, 2, "\n Flags Len LBeg LEnd L"); for (i = 0; i < m->xxh->smp; i++) { flags = read32b(f); m->xxs[i].len = read32b(f); if (flags & 0x02) { m->xxs[i].flg |= WAVE_16_BITS; m->xxs[i].len <<= 1; m->xxs[i].lps <<= 1; m->xxs[i].lpe <<= 1; } if (flags & 0x04) { /* Skip 32-bit samples */ m->xxs[i].len <<= 2; fseek(f, m->xxs[i].len, SEEK_CUR); continue; } xmp_drv_loadpatch(ctx, f, i, m->c4rate, XMP_SMP_BIGEND, &m->xxs[i], NULL); if (m->xxs[i].len == 0) continue; reportv(ctx, 2, "\n[%2X] %08x %05x%c%05x %05x %c ", i, flags, m->xxs[i].len, m->xxs[i].flg & WAVE_16_BITS ? '+' : ' ', m->xxs[i].lps, m->xxs[i].lpe, m->xxs[i].flg & WAVE_LOOPING ? (m->xxs[i].flg & WAVE_BIDIR_LOOP ? 'B' : 'L') : ' '); reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); }
static void get_sbod(struct xmp_context *ctx, int size, FILE *f) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; int flags = 0; int i; if (sample >= m->xxh->ins) return; if (!sample && V(0)) report ("\nStored samples : %d ", m->xxh->smp); i = idx[sample]; if (mode[i] == OKT_MODE8 || mode[i] == OKT_MODEB) flags = XMP_SMP_7BIT; xmp_drv_loadpatch(ctx, f, sample, m->c4rate, flags, &m->xxs[i], NULL); reportv(ctx, 0, "."); sample++; }
static int ptm_load(struct xmp_context *ctx, FILE *f, const int start) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; int c, r, i, smp_ofs[256]; struct xxm_event *event; struct ptm_file_header pfh; struct ptm_instrument_header pih; uint8 n, b; LOAD_INIT(); /* Load and convert header */ fread(&pfh.name, 28, 1, f); /* Song name */ pfh.doseof = read8(f); /* 0x1a */ pfh.vermin = read8(f); /* Minor version */ pfh.vermaj = read8(f); /* Major type */ pfh.rsvd1 = read8(f); /* Reserved */ pfh.ordnum = read16l(f); /* Number of orders (must be even) */ pfh.insnum = read16l(f); /* Number of instruments */ pfh.patnum = read16l(f); /* Number of patterns */ pfh.chnnum = read16l(f); /* Number of channels */ pfh.flags = read16l(f); /* Flags (set to 0) */ pfh.rsvd2 = read16l(f); /* Reserved */ pfh.magic = read32b(f); /* 'PTMF' */ #if 0 if (pfh.magic != MAGIC_PTMF) return -1; #endif fread(&pfh.rsvd3, 16, 1, f); /* Reserved */ fread(&pfh.chset, 32, 1, f); /* Channel settings */ fread(&pfh.order, 256, 1, f); /* Orders */ for (i = 0; i < 128; i++) pfh.patseg[i] = read16l(f); m->xxh->len = pfh.ordnum; m->xxh->ins = pfh.insnum; m->xxh->pat = pfh.patnum; m->xxh->chn = pfh.chnnum; m->xxh->trk = m->xxh->pat * m->xxh->chn; m->xxh->smp = m->xxh->ins; m->xxh->tpo = 6; m->xxh->bpm = 125; memcpy (m->xxo, pfh.order, 256); m->c4rate = C4_NTSC_RATE; copy_adjust((uint8 *)m->name, pfh.name, 28); sprintf(m->type, "PTMF %d.%02x (Poly Tracker)", pfh.vermaj, pfh.vermin); MODULE_INFO(); INSTRUMENT_INIT(); /* Read and convert instruments and samples */ reportv(ctx, 1, " Instrument name Len LBeg LEnd L Vol C4Spd\n"); for (i = 0; i < m->xxh->ins; i++) { m->xxi[i] = calloc (sizeof (struct xxm_instrument), 1); pih.type = read8(f); /* Sample type */ fread(&pih.dosname, 12, 1, f); /* DOS file name */ pih.vol = read8(f); /* Volume */ pih.c4spd = read16l(f); /* C4 speed */ pih.smpseg = read16l(f); /* Sample segment (not used) */ pih.smpofs = read32l(f); /* Sample offset */ pih.length = read32l(f); /* Length */ pih.loopbeg = read32l(f); /* Loop begin */ pih.loopend = read32l(f); /* Loop end */ pih.gusbeg = read32l(f); /* GUS begin address */ pih.guslps = read32l(f); /* GUS loop start address */ pih.guslpe = read32l(f); /* GUS loop end address */ pih.gusflg = read8(f); /* GUS loop flags */ pih.rsvd1 = read8(f); /* Reserved */ fread(&pih.name, 28, 1, f); /* Instrument name */ pih.magic = read32b(f); /* 'PTMS' */ if ((pih.type & 3) != 1) continue; smp_ofs[i] = pih.smpofs; m->xxih[i].nsm = !!(m->xxs[i].len = pih.length); m->xxs[i].lps = pih.loopbeg; m->xxs[i].lpe = pih.loopend; if (m->xxs[i].lpe) m->xxs[i].lpe--; m->xxs[i].flg = pih.type & 0x04 ? WAVE_LOOPING : 0; m->xxs[i].flg |= pih.type & 0x08 ? WAVE_LOOPING | WAVE_BIDIR_LOOP : 0; m->xxs[i].flg |= pih.type & 0x10 ? WAVE_16_BITS : 0; m->xxi[i][0].vol = pih.vol; m->xxi[i][0].pan = 0x80; m->xxi[i][0].sid = i; pih.magic = 0; copy_adjust(m->xxih[i].name, pih.name, 28); if ((V(1)) && (strlen((char *)m->xxih[i].name) || m->xxs[i].len)) report ("[%2X] %-28.28s %05x%c%05x %05x %c V%02x %5d\n", i, m->xxih[i].name, m->xxs[i].len, pih.type & 0x10 ? '+' : ' ', m->xxs[i].lps, m->xxs[i].lpe, m->xxs[i].flg & WAVE_LOOPING ? 'L' : ' ', m->xxi[i][0].vol, pih.c4spd); /* Convert C4SPD to relnote/finetune */ c2spd_to_note (pih.c4spd, &m->xxi[i][0].xpo, &m->xxi[i][0].fin); } PATTERN_INIT(); /* Read patterns */ reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat); for (i = 0; i < m->xxh->pat; i++) { if (!pfh.patseg[i]) continue; PATTERN_ALLOC (i); m->xxp[i]->rows = 64; TRACK_ALLOC (i); fseek(f, start + 16L * pfh.patseg[i], SEEK_SET); r = 0; while (r < 64) { fread (&b, 1, 1, f); if (!b) { r++; continue; } c = b & PTM_CH_MASK; if (c >= m->xxh->chn) continue; event = &EVENT (i, c, r); if (b & PTM_NI_FOLLOW) { fread (&n, 1, 1, f); switch (n) { case 255: n = 0; break; /* Empty note */ case 254: n = XMP_KEY_OFF; break; /* Key off */ } event->note = n; fread (&n, 1, 1, f); event->ins = n; } if (b & PTM_FX_FOLLOWS) { event->fxt = read8(f); event->fxp = read8(f); if (event->fxt > 0x17) event->fxt = event->fxp = 0; switch (event->fxt) { case 0x0e: /* Extended effect */ if (MSN(event->fxp) == 0x8) { /* Pan set */ event->fxt = FX_SETPAN; event->fxp = LSN (event->fxp) << 4; } break; case 0x10: /* Set global volume */ event->fxt = FX_GLOBALVOL; break; case 0x11: /* Multi retrig */ event->fxt = FX_MULTI_RETRIG; break; case 0x12: /* Fine vibrato */ event->fxt = FX_FINE4_VIBRA; break; case 0x13: /* Note slide down */ event->fxt = FX_NSLIDE_DN; break; case 0x14: /* Note slide up */ event->fxt = FX_NSLIDE_UP; break; case 0x15: /* Note slide down + retrig */ event->fxt = FX_NSLIDE_R_DN; break; case 0x16: /* Note slide up + retrig */ event->fxt = FX_NSLIDE_R_UP; break; case 0x17: /* Reverse sample */ event->fxt = event->fxp = 0; break; } } if (b & PTM_VOL_FOLLOWS) { event->vol = read8(f) + 1; } } reportv(ctx, 0, "."); } reportv(ctx, 0, "\nStored samples : %d ", m->xxh->smp); for (i = 0; i < m->xxh->smp; i++) { if (!m->xxs[i].len) continue; fseek(f, start + smp_ofs[m->xxi[i][0].sid], SEEK_SET); xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, XMP_SMP_8BDIFF, &m->xxs[m->xxi[i][0].sid], NULL); reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); m->vol_xlat = ptm_vol; for (i = 0; i < m->xxh->chn; i++) m->xxc[i].pan = pfh.chset[i] << 4; return 0; }
static int mgt_load(struct xmp_context *ctx, FILE *f, const int start) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; struct xxm_event *event; int i, j; int ver; int sng_ptr, seq_ptr, ins_ptr, pat_ptr, trk_ptr, smp_ptr; int sdata[64]; LOAD_INIT(); read24b(f); /* MGT */ ver = read8(f); read32b(f); /* MCS */ sprintf(m->type, "MGT v%d.%d (Megatracker)", MSN(ver), LSN(ver)); m->xxh->chn = read16b(f); read16b(f); /* number of songs */ m->xxh->len = read16b(f); m->xxh->pat = read16b(f); m->xxh->trk = read16b(f); m->xxh->ins = m->xxh->smp = read16b(f); read16b(f); /* reserved */ read32b(f); /* reserved */ sng_ptr = read32b(f); seq_ptr = read32b(f); ins_ptr = read32b(f); pat_ptr = read32b(f); trk_ptr = read32b(f); smp_ptr = read32b(f); read32b(f); /* total smp len */ read32b(f); /* unpacked trk size */ fseek(f, start + sng_ptr, SEEK_SET); fread(m->name, 1, 32, f); seq_ptr = read32b(f); m->xxh->len = read16b(f); m->xxh->rst = read16b(f); m->xxh->bpm = read8(f); m->xxh->tpo = read8(f); read16b(f); /* global volume */ read8(f); /* master L */ read8(f); /* master R */ for (i = 0; i < m->xxh->chn; i++) { read16b(f); /* pan */ } MODULE_INFO(); /* Sequence */ fseek(f, start + seq_ptr, SEEK_SET); for (i = 0; i < m->xxh->len; i++) m->xxo[i] = read16b(f); /* Instruments */ INSTRUMENT_INIT(); fseek(f, start + ins_ptr, SEEK_SET); reportv(ctx, 1, " Name Len LBeg LEnd L Vol C2Spd\n"); for (i = 0; i < m->xxh->ins; i++) { int c2spd, flags; m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1); fread(m->xxih[i].name, 1, 32, f); sdata[i] = read32b(f); m->xxs[i].len = read32b(f); m->xxs[i].lps = read32b(f); m->xxs[i].lpe = m->xxs[i].lps + read32b(f); read32b(f); read32b(f); c2spd = read32b(f); c2spd_to_note(c2spd, &m->xxi[i][0].xpo, &m->xxi[i][0].fin); m->xxi[i][0].vol = read16b(f) >> 4; read8(f); /* vol L */ read8(f); /* vol R */ m->xxi[i][0].pan = 0x80; flags = read8(f); m->xxs[i].flg = flags & 0x03 ? WAVE_LOOPING : 0; m->xxs[i].flg |= flags & 0x02 ? WAVE_BIDIR_LOOP : 0; m->xxi[i][0].fin += 0 * read8(f); // FIXME read8(f); /* unused */ read8(f); read8(f); read8(f); read16b(f); read32b(f); read32b(f); m->xxih[i].nsm = !!m->xxs[i].len; m->xxi[i][0].sid = i; if (V(1) && (strlen((char*)m->xxih[i].name) || (m->xxs[i].len > 1))) { report("[%2X] %-32.32s %04x %04x %04x %c V%02x %5d\n", i, m->xxih[i].name, m->xxs[i].len, m->xxs[i].lps, m->xxs[i].lpe, m->xxs[i].flg & WAVE_BIDIR_LOOP ? 'B' : m->xxs[i].flg & WAVE_LOOPING ? 'L' : ' ', m->xxi[i][0].vol, c2spd); } } /* PATTERN_INIT - alloc extra track*/ PATTERN_INIT(); reportv(ctx, 0, "Stored tracks : %d ", m->xxh->trk); /* Tracks */ for (i = 1; i < m->xxh->trk; i++) { int offset, rows; uint8 b; fseek(f, start + trk_ptr + i * 4, SEEK_SET); offset = read32b(f); fseek(f, start + offset, SEEK_SET); rows = read16b(f); m->xxt[i] = calloc(sizeof(struct xxm_track) + sizeof(struct xxm_event) * rows, 1); m->xxt[i]->rows = rows; //printf("\n=== Track %d ===\n\n", i); for (j = 0; j < rows; j++) { uint8 note, f2p; b = read8(f); j += b & 0x03; note = 0; event = &m->xxt[i]->event[j]; if (b & 0x04) note = read8(f); if (b & 0x08) event->ins = read8(f); if (b & 0x10) event->vol = read8(f); if (b & 0x20) event->fxt = read8(f); if (b & 0x40) event->fxp = read8(f); if (b & 0x80) f2p = read8(f); if (note == 1) event->note = XMP_KEY_OFF; else if (note > 11) /* adjusted to play codeine.mgt */ event->note = note - 11; /* effects */ if (event->fxt < 0x10) /* like amiga */ ; else switch (event->fxt) { case 0x13: case 0x14: case 0x15: case 0x17: case 0x1c: case 0x1d: case 0x1e: event->fxt = FX_EXTENDED; event->fxp = ((event->fxt & 0x0f) << 4) | (event->fxp & 0x0f); break; default: event->fxt = event->fxp = 0; } /* volume and volume column effects */ if ((event->vol >= 0x10) && (event->vol <= 0x50)) { event->vol -= 0x0f; continue; } switch (event->vol >> 4) { case 0x06: /* Volume slide down */ event->f2t = FX_VOLSLIDE_2; event->f2p = event->vol - 0x60; break; case 0x07: /* Volume slide up */ event->f2t = FX_VOLSLIDE_2; event->f2p = (event->vol - 0x70) << 4; break; case 0x08: /* Fine volume slide down */ event->f2t = FX_EXTENDED; event->f2p = (EX_F_VSLIDE_DN << 4) | (event->vol - 0x80); break; case 0x09: /* Fine volume slide up */ event->f2t = FX_EXTENDED; event->f2p = (EX_F_VSLIDE_UP << 4) | (event->vol - 0x90); break; case 0x0a: /* Set vibrato speed */ event->f2t = FX_VIBRATO; event->f2p = (event->vol - 0xa0) << 4; break; case 0x0b: /* Vibrato */ event->f2t = FX_VIBRATO; event->f2p = event->vol - 0xb0; break; case 0x0c: /* Set panning */ event->f2t = FX_SETPAN; event->f2p = ((event->vol - 0xc0) << 4) + 8; break; case 0x0d: /* Pan slide left */ event->f2t = FX_PANSLIDE; event->f2p = (event->vol - 0xd0) << 4; break; case 0x0e: /* Pan slide right */ event->f2t = FX_PANSLIDE; event->f2p = event->vol - 0xe0; break; case 0x0f: /* Tone portamento */ event->f2t = FX_TONEPORTA; event->f2p = (event->vol - 0xf0) << 4; break; } event->vol = 0; /*printf("%02x %02x %02x %02x %02x %02x\n", j, event->note, event->ins, event->vol, event->fxt, event->fxp);*/ } if (V(0) && i % m->xxh->chn == 0) report("."); } reportv(ctx, 0, "\n"); /* Extra track */ m->xxt[0] = calloc(sizeof(struct xxm_track) + sizeof(struct xxm_event) * 64 - 1, 1); m->xxt[0]->rows = 64; /* Read and convert patterns */ reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat); fseek(f, start + pat_ptr, SEEK_SET); for (i = 0; i < m->xxh->pat; i++) { PATTERN_ALLOC(i); m->xxp[i]->rows = read16b(f); for (j = 0; j < m->xxh->chn; j++) { m->xxp[i]->info[j].index = read16b(f) - 1; //printf("%3d ", m->xxp[i]->info[j].index); } reportv(ctx, 0, "."); //printf("\n"); } reportv(ctx, 0, "\n"); /* Read samples */ reportv(ctx, 0, "Stored samples : %d ", m->xxh->smp); for (i = 0; i < m->xxh->ins; i++) { if (m->xxih[i].nsm == 0) continue; fseek(f, start + sdata[i], SEEK_SET); xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, 0, &m->xxs[m->xxi[i][0].sid], NULL); reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); return 0; }
static int med3_load(struct xmp_context *ctx, FILE *f, const int start) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; int i, j; uint32 mask; int transp, sliding; LOAD_INIT(); read32b(f); strcpy(m->type, "MED3 (MED 2.00)"); m->xxh->ins = m->xxh->smp = 32; INSTRUMENT_INIT(); /* read instrument names */ for (i = 0; i < 32; i++) { uint8 c, buf[40]; for (j = 0; j < 40; j++) { c = read8(f); buf[j] = c; if (c == 0) break; } copy_adjust(m->xxih[i].name, buf, 32); m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1); } /* read instrument volumes */ mask = read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { m->xxi[i][0].vol = mask & MASK ? read8(f) : 0; m->xxi[i][0].pan = 0x80; m->xxi[i][0].fin = 0; m->xxi[i][0].sid = i; } /* read instrument loops */ mask = read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { m->xxs[i].lps = mask & MASK ? read16b(f) : 0; } /* read instrument loop length */ mask = read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { uint32 lsiz = mask & MASK ? read16b(f) : 0; m->xxs[i].len = m->xxs[i].lps + lsiz; m->xxs[i].lpe = m->xxs[i].lps + lsiz; m->xxs[i].flg = lsiz > 1 ? WAVE_LOOPING : 0; } m->xxh->chn = 4; m->xxh->pat = read16b(f); m->xxh->trk = m->xxh->chn * m->xxh->pat; m->xxh->len = read16b(f); fread(m->xxo, 1, m->xxh->len, f); m->xxh->tpo = read16b(f); if (m->xxh->tpo > 10) { m->xxh->bpm = 125 * m->xxh->tpo / 33; m->xxh->tpo = 6; } transp = read8s(f); read8(f); /* flags */ sliding = read16b(f); /* sliding */ read32b(f); /* jumping mask */ fseek(f, 16, SEEK_CUR); /* rgb */ /* read midi channels */ mask = read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (mask & MASK) read8(f); } /* read midi programs */ mask = read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (mask & MASK) read8(f); } MODULE_INFO(); reportv(ctx, 0, "Sliding : %d\n", sliding); reportv(ctx, 0, "Play transpose : %d semitones\n", transp); if (sliding == 6) m->quirk |= XMP_QRK_VSALL | XMP_QRK_PBALL; for (i = 0; i < 32; i++) m->xxi[i][0].xpo = transp; PATTERN_INIT(); /* Load and convert patterns */ reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat); for (i = 0; i < m->xxh->pat; i++) { uint32 *conv; uint8 b, tracks; uint16 convsz; PATTERN_ALLOC(i); m->xxp[i]->rows = 64; TRACK_ALLOC(i); tracks = read8(f); b = read8(f); convsz = read16b(f); conv = calloc(1, convsz + 16); assert(conv); if (b & M0F_LINEMSK00) *conv = 0L; else if (b & M0F_LINEMSK0F) *conv = 0xffffffff; else *conv = read32b(f); if (b & M0F_LINEMSK10) *(conv + 1) = 0L; else if (b & M0F_LINEMSK1F) *(conv + 1) = 0xffffffff; else *(conv + 1) = read32b(f); if (b & M0F_FXMSK00) *(conv + 2) = 0L; else if (b & M0F_FXMSK0F) *(conv + 2) = 0xffffffff; else *(conv + 2) = read32b(f); if (b & M0F_FXMSK10) *(conv + 3) = 0L; else if (b & M0F_FXMSK1F) *(conv + 3) = 0xffffffff; else *(conv + 3) = read32b(f); fread(conv + 4, 1, convsz, f); unpack_block(ctx, i, (uint8 *)conv); free(conv); reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); /* Load samples */ reportv(ctx, 0, "Instruments : %d ", m->xxh->ins); reportv(ctx, 1, "\n Instrument name Len LBeg LEnd L Vol"); mask = read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (~mask & MASK) continue; m->xxs[i].len = read32b(f); if (read16b(f)) /* type */ continue; m->xxih[i].nsm = !!(m->xxs[i].len); reportv(ctx, 1, "\n[%2X] %-32.32s %04x %04x %04x %c V%02x ", i, m->xxih[i].name, m->xxs[i].len, m->xxs[i].lps, m->xxs[i].lpe, m->xxs[i].flg & WAVE_LOOPING ? 'L' : ' ', m->xxi[i][0].vol); xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, 0, &m->xxs[m->xxi[i][0].sid], NULL); reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); return 0; }
static int far_load(struct xmp_context *ctx, FILE *f, const int start) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; int i, j, vib = 0; struct xxm_event *event; struct far_header ffh; struct far_header2 ffh2; struct far_instrument fih; uint8 sample_map[8]; LOAD_INIT(); read32b(f); /* File magic: 'FAR\xfe' */ fread(&ffh.name, 40, 1, f); /* Song name */ fread(&ffh.crlf, 3, 1, f); /* 0x0d 0x0a 0x1A */ ffh.headersize = read16l(f); /* Remaining header size in bytes */ ffh.version = read8(f); /* Version MSN=major, LSN=minor */ fread(&ffh.ch_on, 16, 1, f); /* Channel on/off switches */ fseek(f, 9, SEEK_CUR); /* Current editing values */ ffh.tempo = read8(f); /* Default tempo */ fread(&ffh.pan, 16, 1, f); /* Channel pan definitions */ read32l(f); /* Grid, mode (for editor) */ ffh.textlen = read16l(f); /* Length of embedded text */ fseek(f, ffh.textlen, SEEK_CUR); /* Skip song text */ fread(&ffh2.order, 256, 1, f); /* Orders */ ffh2.patterns = read8(f); /* Number of stored patterns (?) */ ffh2.songlen = read8(f); /* Song length in patterns */ ffh2.restart = read8(f); /* Restart pos */ for (i = 0; i < 256; i++) ffh2.patsize[i] = read16l(f); /* Size of each pattern in bytes */ m->xxh->chn = 16; /*m->xxh->pat=ffh2.patterns; (Error in specs? --claudio) */ m->xxh->len = ffh2.songlen; m->xxh->tpo = 6; m->xxh->bpm = 8 * 60 / ffh.tempo; memcpy (m->xxo, ffh2.order, m->xxh->len); for (m->xxh->pat = i = 0; i < 256; i++) { if (ffh2.patsize[i]) m->xxh->pat = i + 1; } m->xxh->trk = m->xxh->chn * m->xxh->pat; strncpy(m->name, (char *)ffh.name, 40); sprintf(m->type, "FAR (Farandole Composer %d.%d)", MSN(ffh.version), LSN(ffh.version)); MODULE_INFO(); PATTERN_INIT(); /* Read and convert patterns */ if (V(0)) { report("Comment bytes : %d\n", ffh.textlen); report("Stored patterns: %d ", m->xxh->pat); } for (i = 0; i < m->xxh->pat; i++) { uint8 brk, note, ins, vol, fxb; PATTERN_ALLOC(i); if (!ffh2.patsize[i]) continue; m->xxp[i]->rows = (ffh2.patsize[i] - 2) / 64; TRACK_ALLOC(i); brk = read8(f) + 1; read8(f); for (j = 0; j < m->xxp[i]->rows * m->xxh->chn; j++) { event = &EVENT(i, j % m->xxh->chn, j / m->xxh->chn); if ((j % m->xxh->chn) == 0 && (j / m->xxh->chn) == brk) event->f2t = FX_BREAK; note = read8(f); ins = read8(f); vol = read8(f); fxb = read8(f); if (note) event->note = note + 36; if (event->note || ins) event->ins = ins + 1; vol = 16 * LSN(vol) + MSN(vol); if (vol) event->vol = vol - 0x10; /* ? */ event->fxt = fx[MSN(fxb)]; event->fxp = LSN(fxb); switch (event->fxt) { case NONE: event->fxt = event->fxp = 0; break; case FX_FAR_PORTA_UP: event->fxt = FX_EXTENDED; event->fxp |= (EX_F_PORTA_UP << 4); break; case FX_FAR_PORTA_DN: event->fxt = FX_EXTENDED; event->fxp |= (EX_F_PORTA_DN << 4); break; case FX_FAR_RETRIG: event->fxt = FX_EXTENDED; event->fxp |= (EX_RETRIG << 4); break; case FX_FAR_DELAY: event->fxt = FX_EXTENDED; event->fxp |= (EX_DELAY << 4); break; case FX_FAR_SETVIBRATO: vib = event->fxp & 0x0f; event->fxt = event->fxp = 0; break; case FX_VIBRATO: event->fxp = (event->fxp << 4) + vib; break; case FX_PER_VIBRATO: event->fxp = (event->fxp << 4) + vib; break; case FX_FAR_VSLIDE_UP: /* Fine volume slide up */ event->fxt = FX_EXTENDED; event->fxp |= (EX_F_VSLIDE_UP << 4); break; case FX_FAR_VSLIDE_DN: /* Fine volume slide down */ event->fxt = FX_EXTENDED; event->fxp |= (EX_F_VSLIDE_DN << 4); break; case FX_TEMPO: event->fxp = 8 * 60 / event->fxp; break; } } reportv(ctx, 0, "."); } m->xxh->ins = -1; fread(sample_map, 1, 8, f); for (i = 0; i < 64; i++) { if (sample_map[i / 8] & (1 << (i % 8))) m->xxh->ins = i; } m->xxh->ins++; m->xxh->smp = m->xxh->ins; INSTRUMENT_INIT(); /* Read and convert instruments and samples */ reportv(ctx, 0, "\nInstruments : %d ", m->xxh->ins); for (i = 0; i < m->xxh->ins; i++) { if (!(sample_map[i / 8] & (1 << (i % 8)))) continue; m->xxi[i] = calloc (sizeof (struct xxm_instrument), 1); fread(&fih.name, 32, 1, f); /* Instrument name */ fih.length = read32l(f); /* Length of sample (up to 64Kb) */ fih.finetune = read8(f); /* Finetune (unsuported) */ fih.volume = read8(f); /* Volume (unsuported?) */ fih.loop_start = read32l(f); /* Loop start */ fih.loopend = read32l(f); /* Loop end */ fih.sampletype = read8(f); /* 1=16 bit sample */ fih.loopmode = read8(f); fih.length &= 0xffff; fih.loop_start &= 0xffff; fih.loopend &= 0xffff; m->xxih[i].nsm = !!(m->xxs[i].len = fih.length); m->xxs[i].lps = fih.loop_start; m->xxs[i].lpe = fih.loopend; m->xxs[i].flg = fih.sampletype ? WAVE_16_BITS : 0; m->xxs[i].flg |= fih.loopmode ? WAVE_LOOPING : 0; m->xxi[i][0].vol = 0xff; /* fih.volume; */ m->xxi[i][0].sid = i; copy_adjust(m->xxih[i].name, fih.name, 32); if (V(1) && (strlen((char *)m->xxih[i].name) || m->xxs[i].len) && m->xxs[i].lps != 0xffff) { report ("\n[%2X] %-32.32s %04x %04x %04x %c V%02x ", i, m->xxih[i].name, m->xxs[i].len, m->xxs[i].lps, m->xxs[i].lpe, fih.loopmode ? 'L' : ' ', m->xxi[i][0].vol); reportv(ctx, 0, "."); } xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, 0, &m->xxs[i], NULL); } reportv(ctx, 0, "\n"); m->volbase = 0xff; return 0; }
static int gdm_load(struct xmp_context *ctx, FILE *f, const int start) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; struct xxm_event *event; int vermaj, vermin, tvmaj, tvmin, tracker; int origfmt, ord_ofs, pat_ofs, ins_ofs, smp_ofs; uint8 buffer[32], panmap[32]; int i; LOAD_INIT(); read32b(f); /* skip magic */ fread(m->name, 1, 32, f); fread(m->author, 1, 32, f); fseek(f, 7, SEEK_CUR); vermaj = read8(f); vermin = read8(f); tracker = read16l(f); tvmaj = read8(f); tvmin = read8(f); if (tracker == 0) { sprintf(m->type, "GDM %d.%02d, (2GDM %d.%02d)", vermaj, vermin, tvmaj, tvmin); } else { sprintf(m->type, "GDM %d.%02d (unknown tracker %d.%02d)", vermaj, vermin, tvmaj, tvmin); } fread(panmap, 32, 1, f); for (i = 0; i < 32; i++) { if (panmap[i] != 0xff) m->xxh->chn = i + 1; if (panmap[i] == 16) panmap[i] = 8; m->xxc[i].pan = 0x80 + (panmap[i] - 8) * 16; } m->xxh->gvl = read8(f); m->xxh->tpo = read8(f); m->xxh->bpm = read8(f); origfmt = read16l(f); ord_ofs = read32l(f); m->xxh->len = read8(f); pat_ofs = read32l(f); m->xxh->pat = read8(f); ins_ofs = read32l(f); smp_ofs = read32l(f); m->xxh->ins = m->xxh->smp = read8(f); m->xxh->trk = m->xxh->pat * m->xxh->chn; MODULE_INFO(); if (origfmt > 9) origfmt = 9; reportv(ctx, 0, "Orig format : %s\n", fmt[origfmt]); fseek(f, start + ord_ofs, SEEK_SET); for (i = 0; i < m->xxh->len; i++) m->xxo[i] = read8(f); /* Read instrument data */ fseek(f, start + ins_ofs, SEEK_SET); INSTRUMENT_INIT(); reportv(ctx, 1, " Name Len LBeg LEnd L Vol Pan C4Spd\n"); for (i = 0; i < m->xxh->ins; i++) { int flg, c4spd, vol, pan; m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1); fread(buffer, 32, 1, f); copy_adjust(m->xxih[i].name, buffer, 32); fseek(f, 12, SEEK_CUR); /* skip filename */ read8(f); /* skip EMS handle */ m->xxs[i].len = read32l(f); m->xxs[i].lps = read32l(f); m->xxs[i].lpe = read32l(f); flg = read8(f); c4spd = read16l(f); vol = read8(f); pan = read8(f); m->xxi[i][0].vol = vol > 0x40 ? 0x40 : vol; m->xxi[i][0].pan = pan > 15 ? 0x80 : 0x80 + (pan - 8) * 16; c2spd_to_note(c4spd, &m->xxi[i][0].xpo, &m->xxi[i][0].fin); m->xxih[i].nsm = !!(m->xxs[i].len); m->xxi[i][0].sid = i; m->xxs[i].flg = 0; if (flg & 0x01) m->xxs[i].flg |= WAVE_LOOPING; if (flg & 0x02) m->xxs[i].flg |= WAVE_16_BITS; if (V(1) && (strlen((char*)m->xxih[i].name) || (m->xxs[i].len > 1))) { report("[%2X] %-32.32s %05x%c%05x %05x %c V%02x P%02x %5d\n", i, m->xxih[i].name, m->xxs[i].len, m->xxs[i].flg & WAVE_16_BITS ? '+' : ' ', m->xxs[i].lps, m->xxs[i].lpe, m->xxs[i].flg & WAVE_LOOPING ? 'L' : ' ', m->xxi[i][0].vol, m->xxi[i][0].pan, c4spd); } } /* Read and convert patterns */ fseek(f, start + pat_ofs, SEEK_SET); PATTERN_INIT(); reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat); for (i = 0; i < m->xxh->pat; i++) { int len, c, r, k; PATTERN_ALLOC(i); m->xxp[i]->rows = 64; TRACK_ALLOC(i); len = read16l(f); len -= 2; for (r = 0; len > 0; ) { c = read8(f); len--; if (c == 0) { r++; continue; } assert((c & 0x1f) < m->xxh->chn); event = &EVENT (i, c & 0x1f, r); if (c & 0x20) { /* note and sample follows */ k = read8(f); event->note = 12 * MSN(k & 0x7f) + LSN(k); event->ins = read8(f); len -= 2; } if (c & 0x40) { /* effect(s) follow */ do { k = read8(f); len--; switch ((k & 0xc0) >> 6) { case 0: event->fxt = k & 0x1f; event->fxp = read8(f); len--; fix_effect(&event->fxt, &event->fxp); break; case 1: event->f2t = k & 0x1f; event->f2p = read8(f); len--; fix_effect(&event->f2t, &event->f2p); break; case 2: read8(f); len--; } } while (k & 0x20); } } reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); /* Read samples */ fseek(f, start + smp_ofs, SEEK_SET); reportv(ctx, 0, "Stored samples : %d ", m->xxh->smp); for (i = 0; i < m->xxh->ins; i++) { xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, XMP_SMP_UNS, &m->xxs[m->xxi[i][0].sid], NULL); reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); return 0; }