void read_title(FILE *f, char *t, int s) { uint8 buf[XMP_NAMESIZE]; if (t == NULL) return; if (s >= XMP_NAMESIZE) s = XMP_NAMESIZE -1; memset(t, 0, s + 1); fread(buf, 1, s, f); buf[s] = 0; copy_adjust((uint8 *)t, buf, s); }
void read_title(HIO_HANDLE *f, char *t, int s) { uint8 buf[XMP_NAME_SIZE]; if (t == NULL) return; if (s >= XMP_NAME_SIZE) s = XMP_NAME_SIZE -1; memset(t, 0, s + 1); hio_read(buf, 1, s, f); buf[s] = 0; copy_adjust(t, buf, s); }
static void get_inst(struct xmp_context *ctx, int size, FILE *f) { struct xmp_player_context *p = &ctx->p; struct xmp_mod_context *m = &p->m; int i; int c2spd, flags, snum; uint8 buffer[50]; reportv(ctx, 0, "Instruments : %d ", m->xxh->ins); reportv(ctx, 1, "\n Instrument name Smp Vol Pan C2Spd"); for (i = 0; i < m->xxh->ins; i++) { m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1); m->xxih[i].nsm = 1; fread(buffer, 30, 1, f); copy_adjust(m->xxih[i].name, buffer, 30); snum = read16b(f); if (snum == 0 || snum > m->xxh->smp) continue; m->xxi[i][0].sid = --snum; m->xxi[i][0].vol = read16b(f); c2spd = read32b(f); m->xxs[snum].lps = read32b(f); m->xxs[snum].lpe = m->xxs[i].lps + read32b(f); m->xxi[i][0].pan = 0x80 + (int16)read16b(f); if (m->xxi[i][0].pan > 0xff) m->xxi[i][0].pan = 0xff; flags = read16b(f); m->xxs[snum].flg = flags & 0x03 ? WAVE_LOOPING : 0; m->xxs[snum].flg |= flags & 0x02 ? WAVE_BIDIR_LOOP : 0; c2spd_to_note(c2spd, &m->xxi[i][0].xpo, &m->xxi[i][0].fin); reportv(ctx, 1, "\n[%2X] %-30.30s #%02X V%02x P%02x %5d ", i, m->xxih[i].name, snum, m->xxi[i][0].vol, m->xxi[i][0].pan, c2spd); reportv(ctx, 0, "."); } reportv(ctx, 0, "\n"); }
static void get_inst(struct module_data *m, int size, FILE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; int c2spd, flags, snum; uint8 buffer[50]; D_(D_INFO "Instruments: %d", mod->ins); for (i = 0; i < mod->ins; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); mod->xxi[i].nsm = 1; fread(buffer, 30, 1, f); copy_adjust(mod->xxi[i].name, buffer, 30); snum = read16b(f); if (snum == 0 || snum > mod->smp) continue; mod->xxi[i].sub[0].sid = --snum; mod->xxi[i].sub[0].vol = read16b(f); c2spd = read32b(f); mod->xxs[snum].lps = read32b(f); mod->xxs[snum].lpe = mod->xxs[i].lps + read32b(f); mod->xxi[i].sub[0].pan = 0x80 + (int16)read16b(f); if (mod->xxi[i].sub[0].pan > 0xff) mod->xxi[i].sub[0].pan = 0xff; flags = read16b(f); mod->xxs[snum].flg = flags & 0x03 ? XMP_SAMPLE_LOOP : 0; mod->xxs[snum].flg |= flags & 0x02 ? XMP_SAMPLE_LOOP_BIDIR : 0; c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); D_(D_INFO "[%2X] %-30.30s #%02X V%02x P%02x %5d", i, mod->xxi[i].name, snum, mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].pan, c2spd); } }
static int stm_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct xmp_event *event; struct stm_file_header sfh; uint8 b; int bmod2stm = 0; LOAD_INIT(); hio_read(&sfh.name, 20, 1, f); /* ASCIIZ song name */ hio_read(&sfh.magic, 8, 1, f); /* '!Scream!' */ sfh.rsvd1 = hio_read8(f); /* '\x1a' */ sfh.type = hio_read8(f); /* 1=song, 2=module */ sfh.vermaj = hio_read8(f); /* Major version number */ sfh.vermin = hio_read8(f); /* Minor version number */ sfh.tempo = hio_read8(f); /* Playback tempo */ sfh.patterns = hio_read8(f); /* Number of patterns */ sfh.gvol = hio_read8(f); /* Global volume */ hio_read(&sfh.rsvd2, 13, 1, f); /* Reserved */ for (i = 0; i < 31; i++) { hio_read(&sfh.ins[i].name, 12, 1, f); /* ASCIIZ instrument name */ sfh.ins[i].id = hio_read8(f); /* Id=0 */ sfh.ins[i].idisk = hio_read8(f); /* Instrument disk */ sfh.ins[i].rsvd1 = hio_read16l(f); /* Reserved */ sfh.ins[i].length = hio_read16l(f); /* Sample length */ sfh.ins[i].loopbeg = hio_read16l(f); /* Loop begin */ sfh.ins[i].loopend = hio_read16l(f); /* Loop end */ sfh.ins[i].volume = hio_read8(f); /* Playback volume */ sfh.ins[i].rsvd2 = hio_read8(f); /* Reserved */ sfh.ins[i].c2spd = hio_read16l(f); /* C4 speed */ sfh.ins[i].rsvd3 = hio_read32l(f); /* Reserved */ sfh.ins[i].paralen = hio_read16l(f); /* Length in paragraphs */ } if (!strncmp ((char *)sfh.magic, "BMOD2STM", 8)) bmod2stm = 1; mod->pat = sfh.patterns; mod->trk = mod->pat * mod->chn; mod->spd = MSN (sfh.tempo); mod->ins = 31; mod->smp = mod->ins; m->c4rate = C4_NTSC_RATE; copy_adjust(mod->name, sfh.name, 20); if (bmod2stm) { snprintf(mod->type, XMP_NAME_SIZE, "BMOD2STM STM"); } else { snprintf(mod->type, XMP_NAME_SIZE, "Scream Tracker %d.%02d STM", sfh.vermaj, sfh.vermin); } MODULE_INFO(); if (instrument_init(mod) < 0) return -1; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; mod->xxs[i].len = sfh.ins[i].length; mod->xxs[i].lps = sfh.ins[i].loopbeg; mod->xxs[i].lpe = sfh.ins[i].loopend; if (mod->xxs[i].lpe == 0xffff) mod->xxs[i].lpe = 0; mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].vol = sfh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; instrument_name(mod, i, sfh.ins[i].name, 12); D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, sfh.ins[i].c2spd); sfh.ins[i].c2spd = 8363 * sfh.ins[i].c2spd / 8448; c2spd_to_note (sfh.ins[i].c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); } hio_read(mod->xxo, 1, 128, f); for (i = 0; i < 128; i++) if (mod->xxo[i] >= mod->pat) break; mod->len = i; D_(D_INFO "Module length: %d", mod->len); if (pattern_init(mod) < 0) return -1; /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < 64 * mod->chn; j++) { event = &EVENT (i, j % mod->chn, j / mod->chn); b = hio_read8(f); memset (event, 0, sizeof (struct xmp_event)); switch (b) { case 251: case 252: case 253: break; case 255: b = 0; default: event->note = b ? 13 + LSN(b) + 12 * (2 + MSN(b)) : 0; b = hio_read8(f); event->vol = b & 0x07; event->ins = (b & 0xf8) >> 3; b = hio_read8(f); event->vol += (b & 0xf0) >> 1; if (event->vol > 0x40) event->vol = 0; else event->vol++; event->fxt = fx[LSN(b)]; event->fxp = hio_read8(f); switch (event->fxt) { case FX_SPEED: event->fxp = MSN (event->fxp); break; case FX_NONE: event->fxp = event->fxt = 0; break; } } } } /* Read samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->ins; i++) { if (mod->xxs[i].len > 1) { if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; } else { mod->xxi[i].nsm = 0; } } m->quirk |= QUIRK_VSALL | QUIRKS_ST3; m->read_event_type = READ_EVENT_ST3; return 0; }
static int far_load(struct module_data *m, FILE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j, vib = 0; struct xmp_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 */ mod->chn = 16; /*mod->pat=ffh2.patterns; (Error in specs? --claudio) */ mod->len = ffh2.songlen; mod->spd = 6; mod->bpm = 8 * 60 / ffh.tempo; memcpy (mod->xxo, ffh2.order, mod->len); for (mod->pat = i = 0; i < 256; i++) { if (ffh2.patsize[i]) mod->pat = i + 1; } mod->trk = mod->chn * mod->pat; strncpy(mod->name, (char *)ffh.name, 40); set_type(m, "Farandole Composer %d.%d", MSN(ffh.version), LSN(ffh.version)); MODULE_INFO(); PATTERN_INIT(); /* Read and convert patterns */ D_(D_INFO "Comment bytes : %d", ffh.textlen); D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { uint8 brk, note, ins, vol, fxb; PATTERN_ALLOC(i); if (!ffh2.patsize[i]) continue; mod->xxp[i]->rows = (ffh2.patsize[i] - 2) / 64; TRACK_ALLOC(i); brk = read8(f) + 1; read8(f); for (j = 0; j < mod->xxp[i]->rows * mod->chn; j++) { event = &EVENT(i, j % mod->chn, j / mod->chn); if ((j % mod->chn) == 0 && (j / mod->chn) == brk) event->f2t = FX_BREAK; note = read8(f); ins = read8(f); vol = read8(f); fxb = read8(f); if (note) event->note = note + 48; 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_SPEED: event->fxp = 8 * 60 / event->fxp; break; } } } mod->ins = -1; fread(sample_map, 1, 8, f); for (i = 0; i < 64; i++) { if (sample_map[i / 8] & (1 << (i % 8))) mod->ins = i; } mod->ins++; mod->smp = mod->ins; INSTRUMENT_INIT(); /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { if (!(sample_map[i / 8] & (1 << (i % 8)))) continue; mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 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; mod->xxs[i].len = fih.length; mod->xxi[i].nsm = fih.length > 0 ? 1 : 0; mod->xxs[i].lps = fih.loop_start; mod->xxs[i].lpe = fih.loopend; mod->xxs[i].flg = 0; if (fih.sampletype != 0) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } mod->xxs[i].flg |= fih.loopmode ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].vol = 0xff; /* fih.volume; */ mod->xxi[i].sub[0].sid = i; copy_adjust(mod->xxi[i].name, fih.name, 32); D_(D_INFO "[%2X] %-32.32s %04x %04x %04x %c V%02x", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, fih.loopmode ? 'L' : ' ', mod->xxi[i].sub[0].vol); load_sample(f, 0, &mod->xxs[i], NULL); }
static int gdm_load(struct module_data *m, xmp_file f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_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 */ xmp_fread(mod->name, 1, 32, f); xmp_fseek(f, 32, SEEK_CUR); /* skip author */ xmp_fseek(f, 7, SEEK_CUR); vermaj = read8(f); vermin = read8(f); tracker = read16l(f); tvmaj = read8(f); tvmin = read8(f); if (tracker == 0) { set_type(m, "GDM %d.%02d (2GDM %d.%02d)", vermaj, vermin, tvmaj, tvmin); } else { set_type(m, "GDM %d.%02d (unknown tracker %d.%02d)", vermaj, vermin, tvmaj, tvmin); } xmp_fread(panmap, 32, 1, f); for (i = 0; i < 32; i++) { if (panmap[i] != 0xff) mod->chn = i + 1; if (panmap[i] == 16) panmap[i] = 8; mod->xxc[i].pan = 0x80 + (panmap[i] - 8) * 16; } mod->gvl = read8(f); mod->spd = read8(f); mod->bpm = read8(f); origfmt = read16l(f); ord_ofs = read32l(f); mod->len = read8(f) + 1; pat_ofs = read32l(f); mod->pat = read8(f) + 1; ins_ofs = read32l(f); smp_ofs = read32l(f); mod->ins = mod->smp = read8(f) + 1; mod->trk = mod->pat * mod->chn; MODULE_INFO(); xmp_fseek(f, start + ord_ofs, SEEK_SET); for (i = 0; i < mod->len; i++) mod->xxo[i] = read8(f); /* Read instrument data */ xmp_fseek(f, start + ins_ofs, SEEK_SET); INSTRUMENT_INIT(); for (i = 0; i < mod->ins; i++) { int flg, c4spd, vol, pan; mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); xmp_fread(buffer, 32, 1, f); copy_adjust(mod->xxi[i].name, buffer, 32); xmp_fseek(f, 12, SEEK_CUR); /* skip filename */ read8(f); /* skip EMS handle */ mod->xxs[i].len = read32l(f); mod->xxs[i].lps = read32l(f); mod->xxs[i].lpe = read32l(f); flg = read8(f); c4spd = read16l(f); vol = read8(f); pan = read8(f); mod->xxi[i].sub[0].vol = vol > 0x40 ? 0x40 : vol; mod->xxi[i].sub[0].pan = pan > 15 ? 0x80 : 0x80 + (pan - 8) * 16; c2spd_to_note(c4spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxi[i].nsm = !!(mod->xxs[i].len); mod->xxi[i].sub[0].sid = i; mod->xxs[i].flg = 0; if (flg & 0x01) { mod->xxs[i].flg |= XMP_SAMPLE_LOOP; } if (flg & 0x02) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } D_(D_INFO "[%2X] %-32.32s %05x%c%05x %05x %c V%02x P%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ', mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].pan, c4spd); }
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; }
static int gtk_load(struct module_data *m, FILE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j, k; uint8 buffer[40]; int rows, bits, c2spd, size; int ver, patmax; LOAD_INIT(); fread(buffer, 4, 1, f); ver = buffer[3]; fread(mod->name, 32, 1, f); set_type(m, "Graoumf Tracker GTK v%d", ver); fseek(f, 160, SEEK_CUR); /* skip comments */ mod->ins = read16b(f); mod->smp = mod->ins; rows = read16b(f); mod->chn = read16b(f); mod->len = read16b(f); mod->rst = read16b(f); MODULE_INFO(); D_(D_INFO "Instruments : %d ", mod->ins); INSTRUMENT_INIT(); for (i = 0; i < mod->ins; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); fread(buffer, 28, 1, f); copy_adjust(mod->xxi[i].name, buffer, 28); if (ver == 1) { read32b(f); mod->xxs[i].len = read32b(f); mod->xxs[i].lps = read32b(f); size = read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + size - 1; read16b(f); read16b(f); mod->xxi[i].sub[0].vol = 0x40; mod->xxi[i].sub[0].pan = 0x80; bits = 1; c2spd = 8363; } else { fseek(f, 14, SEEK_CUR); read16b(f); /* autobal */ bits = read16b(f); /* 1 = 8 bits, 2 = 16 bits */ c2spd = read16b(f); c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxs[i].len = read32b(f); mod->xxs[i].lps = read32b(f); size = read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + size - 1; mod->xxi[i].sub[0].vol = read16b(f) / 4; read8(f); mod->xxi[i].sub[0].fin = read8s(f); } mod->xxi[i].nsm = !!mod->xxs[i].len; mod->xxi[i].sub[0].sid = i; mod->xxs[i].flg = size > 2 ? XMP_SAMPLE_LOOP : 0; if (bits > 1) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } D_(D_INFO "[%2X] %-28.28s %05x%c%05x %05x %c " "V%02x F%+03d %5d", i, mod->xxi[i].name, mod->xxs[i].len, bits > 1 ? '+' : ' ', mod->xxs[i].lps, size, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin, c2spd); }
static int stx_load(struct module_data *m, xmp_file f, const int start) { struct xmp_module *mod = &m->mod; int c, r, i, broken = 0; struct xmp_event *event = 0, dummy; struct stx_file_header sfh; struct stx_instrument_header sih; uint8 n, b; uint16 x16; int bmod2stm = 0; uint16 *pp_ins; /* Parapointers to instruments */ uint16 *pp_pat; /* Parapointers to patterns */ LOAD_INIT(); xmp_fread(&sfh.name, 20, 1, f); xmp_fread(&sfh.magic, 8, 1, f); sfh.psize = read16l(f); sfh.unknown1 = read16l(f); sfh.pp_pat = read16l(f); sfh.pp_ins = read16l(f); sfh.pp_chn = read16l(f); sfh.unknown2 = read16l(f); sfh.unknown3 = read16l(f); sfh.gvol = read8(f); sfh.tempo = read8(f); sfh.unknown4 = read16l(f); sfh.unknown5 = read16l(f); sfh.patnum = read16l(f); sfh.insnum = read16l(f); sfh.ordnum = read16l(f); sfh.unknown6 = read16l(f); sfh.unknown7 = read16l(f); sfh.unknown8 = read16l(f); xmp_fread(&sfh.magic2, 4, 1, f); /* BMOD2STM does not convert pitch */ if (!strncmp ((char *) sfh.magic, "BMOD2STM", 8)) bmod2stm = 1; #if 0 if ((strncmp ((char *) sfh.magic, "!Scream!", 8) && !bmod2stm) || strncmp ((char *) sfh.magic2, "SCRM", 4)) return -1; #endif mod->ins = sfh.insnum; mod->pat = sfh.patnum; mod->trk = mod->pat * mod->chn; mod->len = sfh.ordnum; mod->spd = MSN (sfh.tempo); mod->smp = mod->ins; m->c4rate = C4_NTSC_RATE; /* STM2STX 1.0 released with STMIK 0.2 converts STMs with the pattern * length encoded in the first two bytes of the pattern (like S3M). */ xmp_fseek(f, start + (sfh.pp_pat << 4), SEEK_SET); x16 = read16l(f); xmp_fseek(f, start + (x16 << 4), SEEK_SET); x16 = read16l(f); if (x16 == sfh.psize) broken = 1; strncpy(mod->name, (char *)sfh.name, 20); if (bmod2stm) set_type(m, "BMOD2STM STX"); else snprintf(mod->type, XMP_NAME_SIZE, "STM2STX 1.%d", broken ? 0 : 1); MODULE_INFO(); pp_pat = calloc (2, mod->pat); pp_ins = calloc (2, mod->ins); /* Read pattern pointers */ xmp_fseek(f, start + (sfh.pp_pat << 4), SEEK_SET); for (i = 0; i < mod->pat; i++) pp_pat[i] = read16l(f); /* Read instrument pointers */ xmp_fseek(f, start + (sfh.pp_ins << 4), SEEK_SET); for (i = 0; i < mod->ins; i++) pp_ins[i] = read16l(f); /* Skip channel table (?) */ xmp_fseek(f, start + (sfh.pp_chn << 4) + 32, SEEK_SET); /* Read orders */ for (i = 0; i < mod->len; i++) { mod->xxo[i] = read8(f); xmp_fseek(f, 4, SEEK_CUR); } INSTRUMENT_INIT(); /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); xmp_fseek(f, start + (pp_ins[i] << 4), SEEK_SET); sih.type = read8(f); xmp_fread(&sih.dosname, 13, 1, f); sih.memseg = read16l(f); sih.length = read32l(f); sih.loopbeg = read32l(f); sih.loopend = read32l(f); sih.vol = read8(f); sih.rsvd1 = read8(f); sih.pack = read8(f); sih.flags = read8(f); sih.c2spd = read16l(f); sih.rsvd2 = read16l(f); xmp_fread(&sih.rsvd3, 4, 1, f); sih.int_gp = read16l(f); sih.int_512 = read16l(f); sih.int_last = read32l(f); xmp_fread(&sih.name, 28, 1, f); xmp_fread(&sih.magic, 4, 1, f); mod->xxi[i].nsm = !!(mod->xxs[i].len = sih.length); mod->xxs[i].lps = sih.loopbeg; mod->xxs[i].lpe = sih.loopend; if (mod->xxs[i].lpe == 0xffff) mod->xxs[i].lpe = 0; mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].vol = sih.vol; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; copy_adjust(mod->xxi[i].name, sih.name, 12); D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d\n", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, sih.c2spd); sih.c2spd = 8363 * sih.c2spd / 8448; c2spd_to_note(sih.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); } PATTERN_INIT(); /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { PATTERN_ALLOC (i); mod->xxp[i]->rows = 64; TRACK_ALLOC (i); if (!pp_pat[i]) continue; xmp_fseek(f, start + (pp_pat[i] << 4), SEEK_SET); if (broken) xmp_fseek(f, 2, SEEK_CUR); for (r = 0; r < 64; ) { b = read8(f); if (b == S3M_EOR) { r++; continue; } c = b & S3M_CH_MASK; event = c >= mod->chn ? &dummy : &EVENT (i, c, r); if (b & S3M_NI_FOLLOW) { n = read8(f); switch (n) { case 255: n = 0; break; /* Empty note */ case 254: n = XMP_KEY_OFF; break; /* Key off */ default: n = 37 + 12 * MSN (n) + LSN (n); } event->note = n; event->ins = read8(f);; } if (b & S3M_VOL_FOLLOWS) { event->vol = read8(f) + 1; } if (b & S3M_FX_FOLLOWS) { event->fxt = fx[read8(f)]; event->fxp = read8(f); switch (event->fxt) { case FX_SPEED: event->fxp = MSN (event->fxp); break; case FX_NONE: event->fxp = event->fxt = 0; break; } } } } free (pp_pat); free (pp_ins); /* Read samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->ins; i++) { load_sample(m, f, 0, &mod->xxs[mod->xxi[i].sub[0].sid], NULL); } m->quirk |= QUIRK_VSALL | QUIRKS_ST3; m->read_event_type = READ_EVENT_ST3; return 0; }
static int stc_load(struct module_data *m, HIO_HANDLE * f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event /*, *noise*/; int i, j; uint8 buf[100]; int pos_ptr, orn_ptr, pat_ptr; struct stc_ord stc_ord[256]; struct stc_pat stc_pat[MAX_PAT]; int num, flag, orn; int *decoded; struct spectrum_extra *se; LOAD_INIT(); mod->spd = hio_read8(f); /* Speed */ pos_ptr = hio_read16l(f); /* Positions pointer */ orn_ptr = hio_read16l(f); /* Ornaments pointer */ pat_ptr = hio_read16l(f); /* Patterns pointer */ hio_read(buf, 18, 1, f); /* Title */ copy_adjust(mod->name, (uint8 *)buf, 18); set_type(m, "ZX Spectrum Sound Tracker"); hio_read16l(f); /* Size */ /* Read orders */ hio_seek(f, pos_ptr, SEEK_SET); mod->len = hio_read8(f) + 1; for (num = i = 0; i < mod->len; i++) { stc_ord[i].pattern = hio_read8(f); stc_ord[i].height = hio_read8s(f); //printf("%d %d -- ", stc_ord[i].pattern, stc_ord[i].height); for (flag = j = 0; j < i; j++) { if (stc_ord[i].pattern == stc_ord[j].pattern && stc_ord[i].height == stc_ord[j].height) { mod->xxo[i] = mod->xxo[j]; flag = 1; break; } } if (!flag) { mod->xxo[i] = num++; } //printf("%d\n", mod->xxo[i]); } mod->chn = 3; mod->pat = num; mod->trk = mod->pat * mod->chn; mod->ins = 15; mod->smp = mod->ins; orn = (pat_ptr - orn_ptr) / 33; MODULE_INFO(); /* Read patterns */ if (pattern_init(mod) < 0) return -1; hio_seek(f, pat_ptr, SEEK_SET); decoded = calloc(mod->pat, sizeof(int)); D_(D_INFO "Stored patterns: %d ", mod->pat); for (i = 0; i < MAX_PAT; i++) { if (hio_read8(f) == 0xff) break; stc_pat[i].ch[0] = hio_read16l(f); stc_pat[i].ch[1] = hio_read16l(f); stc_pat[i].ch[2] = hio_read16l(f); } for (i = 0; i < mod->len; i++) { /* pattern */ int src = stc_ord[i].pattern - 1; int dest = mod->xxo[i]; int trans = stc_ord[i].height; if (decoded[dest]) continue; //printf("%d/%d) Read pattern %d -> %d\n", i, mod->len, src, dest); if (pattern_tracks_alloc(mod, dest, 64) < 0) return -1; for (j = 0; j < 3; j++) { /* row */ int row = 0; int x; int rowinc = 0; hio_seek(f, stc_pat[src].ch[j], SEEK_SET); do { for (;;) { x = hio_read8(f); if (x == 0xff) break; //printf("pat %d, channel %d, row %d, x = %02x\n", dest, j, row, x); event = &EVENT(dest, j, row); if (x <= 0x5f) { event->note = x + 18 + trans; row += 1 + rowinc; break; } if (x <= 0x6f) { event->ins = x - 0x5f - 1; } else if (x <= 0x7f) { /* ornament*/ event->fxt = FX_SYNTH_0; event->fxp = x - 0x70; } else if (x == 0x80) { event->note = XMP_KEY_OFF; row += 1 + rowinc; break; } else if (x == 0x81) { /* ? */ row += 1 + rowinc; } else if (x == 0x82) { /* disable ornament/envelope */ event->fxt = FX_SYNTH_0; event->fxp = 0; event->f2t = FX_SYNTH_2; event->f2p = 0; } else if (x <= 0x8e) { /* envelope */ event->fxt = FX_SYNTH_0 + x - 0x80; /* R13 */ event->fxp = hio_read8(f); /* R11 */ event->f2t = FX_SYNTH_1; event->f2p = hio_read8(f); /* R12 */ } else { rowinc = x - 0xa1; } } } while (x != 0xff); } decoded[dest] = 1; } free(decoded); /* Read instruments */ if (instrument_init(mod) < 0) return -1; hio_seek(f, 27, SEEK_SET); D_(D_INFO "Instruments: %d", mod->ins); for (i = 0; i < mod->ins; i++) { struct spectrum_sample ss; memset(&ss, 0, sizeof (struct spectrum_sample)); if (subinstrument_alloc(mod, i, 1) < 0) return -1; mod->xxi[i].nsm = 1; mod->xxi[i].sub[0].vol = 0x40; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].xpo = -1; mod->xxi[i].sub[0].sid = i; hio_read(buf, 1, 99, f); if (buf[97] == 0) { ss.loop = 32; ss.length = 33; } else { ss.loop = buf[97] - 1; if (ss.loop > 31) ss.loop = 31; ss.length = buf[97] + buf[98]; if (ss.length > 32) ss.length = 32; if (ss.length == 0) ss.length = 1; if (ss.loop >= ss.length) ss.loop = ss.length - 1; if (ss.length < 32) { ss.length += 33 - (ss.loop + 1); ss.loop = 32; } } /* Read sample ticks */ for (j = 0; j < 31; j++) { struct spectrum_stick *sst = &ss.stick[j]; uint8 *chdata = &buf[1 + j * 3]; memset(sst, 0, sizeof (struct spectrum_stick)); if (~chdata[1] & 0x80) { sst->flags |= SPECTRUM_FLAG_MIXNOISE; sst->noise_env_inc = chdata[1] & 0x1f; if (sst->noise_env_inc & 0x10) sst->noise_env_inc |= 0xf0; } if (~chdata[1] & 0x40) sst->flags |= SPECTRUM_FLAG_MIXTONE; sst->vol = chdata[0] & 0x0f; sst->tone_inc = (((int)(chdata[0] & 0xf0)) << 4) | chdata[2]; if (~chdata[1] & 0x20) sst->tone_inc = -sst->tone_inc; sst->flags |= SPECTRUM_FLAG_ENVELOPE; /*if (j != 0) { reportv(ctx, 1, " "); } reportv(ctx, 1, "%02X %c%c%c %c%03x %x\n", j, sst->flags & SPECTRUM_FLAG_MIXTONE ? 'T' : 't', sst->flags & SPECTRUM_FLAG_MIXNOISE ? 'N' : 'n', sst->flags & SPECTRUM_FLAG_ENVELOPE ? 'E' : 'e', sst->tone_inc >= 0 ? '+' : '-', sst->tone_inc >= 0 ? sst->tone_inc : -sst->tone_inc, sst->vol);*/ } if (load_sample(m, f, SAMPLE_FLAG_SPECTRUM, &mod->xxs[i], (char *)&ss) < 0) { return -1; } } /* Read ornaments */ hio_seek(f, orn_ptr, SEEK_SET); m->extra = calloc(1, sizeof (struct spectrum_extra)); se = m->extra; D_(D_INFO "Ornaments: %d", orn); for (i = 0; i < orn; i++) { int index; struct spectrum_ornament *so; index = hio_read8(f); so = &se->ornament[index]; so->length = 32; so->loop = 31; for (j = 0; j < 32; j++) { so->val[j] = hio_read8s(f); } } for (i = 0; i < 4; i++) { mod->xxc[i].pan = 0x80; mod->xxc[i].flg = XMP_CHANNEL_SYNTH; } m->synth = &synth_spectrum; return 0; }
static int mtp_load(struct module_data *m, xmp_file f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j, k; uint8 buffer[25]; int blocksize; xmp_file s; LOAD_INIT(); xmp_fread(buffer, 6, 1, f); if (!memcmp(buffer, "SONGOK", 6)) set_type(m, "IIgs SoundSmith"); else if (!memcmp(buffer, "IAN92a", 8)) set_type(m, "IIgs MegaTracker"); else return -1; blocksize = read16l(f); mod->spd = read16l(f); xmp_fseek(f, 10, SEEK_CUR); /* skip 10 reserved bytes */ mod->ins = mod->smp = 15; INSTRUMENT_INIT(); for (i = 0; i < mod->ins; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); xmp_fread(buffer, 1, 22, f); if (buffer[0]) { buffer[buffer[0] + 1] = 0; copy_adjust(mod->xxi[i].name, buffer + 1, 22); } read16l(f); /* skip 2 reserved bytes */ mod->xxi[i].sub[0].vol = read8(f) >> 2; mod->xxi[i].sub[0].pan = 0x80; xmp_fseek(f, 5, SEEK_CUR); /* skip 5 bytes */ } mod->len = read8(f) & 0x7f; read8(f); xmp_fread(mod->xxo, 1, 128, f); MODULE_INFO(); xmp_fseek(f, start + 600, SEEK_SET); mod->chn = 14; mod->pat = blocksize / (14 * 64); mod->trk = mod->pat * mod->chn; PATTERN_INIT(); /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); /* Load notes */ for (i = 0; i < mod->pat; i++) { PATTERN_ALLOC(i); mod->xxp[i]->rows = 64; TRACK_ALLOC(i); for (j = 0; j < mod->xxp[i]->rows; j++) { for (k = 0; k < mod->chn; k++) { event = &EVENT(i, k, j); event->note = read8(f);; if (event->note) event->note += 24; } } } /* Load fx1 */ for (i = 0; i < mod->pat; i++) { for (j = 0; j < mod->xxp[i]->rows; j++) { for (k = 0; k < mod->chn; k++) { uint8 x; event = &EVENT(i, k, j); x = read8(f);; event->ins = x >> 4; switch (x & 0x0f) { case 0x00: event->fxt = FX_ARPEGGIO; break; case 0x03: event->fxt = FX_VOLSET; break; case 0x05: event->fxt = FX_VOLSLIDE_DN; break; case 0x06: event->fxt = FX_VOLSLIDE_UP; break; case 0x0f: event->fxt = FX_SPEED; break; } } } } /* Load fx2 */ for (i = 0; i < mod->pat; i++) { for (j = 0; j < mod->xxp[i]->rows; j++) { for (k = 0; k < mod->chn; k++) { event = &EVENT(i, k, j); event->fxp = read8(f);; switch (event->fxt) { case FX_VOLSET: case FX_VOLSLIDE_DN: case FX_VOLSLIDE_UP: event->fxp >>= 2; } } } } /* Read instrument data */ D_(D_INFO "Instruments : %d ", mod->ins); for (i = 0; i < mod->ins; i++) { char filename[1024]; if (!mod->xxi[i].name[0]) continue; strncpy(filename, m->dirname, NAME_SIZE); if (*filename) strncat(filename, "/", NAME_SIZE); strncat(filename, (char *)mod->xxi[i].name, NAME_SIZE); if ((s = xmp_fopen(filename, "rb")) != NULL) { asif_load(m, s, i); xmp_fclose(s); } #if 0 mod->xxs[i].lps = 0; mod->xxs[i].lpe = 0; mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].fin = 0; mod->xxi[i].sub[0].pan = 0x80; #endif D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol); } return 0; }
static int ims_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; int smp_size; struct xxm_event *event; struct ims_header ih; uint8 ims_event[3]; int xpo = 21; /* Tuned against UADE */ LOAD_INIT(); m->xxh->ins = 31; m->xxh->smp = m->xxh->ins; smp_size = 0; fread (&ih.title, 20, 1, f); for (i = 0; i < 31; i++) { fread (&ih.ins[i].name, 20, 1, f); ih.ins[i].finetune = (int16)read16b(f); ih.ins[i].size = read16b(f); ih.ins[i].unknown = read8(f); ih.ins[i].volume = read8(f); ih.ins[i].loop_start = read16b(f); ih.ins[i].loop_size = read16b(f); smp_size += ih.ins[i].size * 2; } ih.len = read8(f); ih.zero = read8(f); fread (&ih.orders, 128, 1, f); fread (&ih.magic, 4, 1, f); m->xxh->len = ih.len; memcpy (m->xxo, ih.orders, m->xxh->len); for (i = 0; i < m->xxh->len; i++) if (m->xxo[i] > m->xxh->pat) m->xxh->pat = m->xxo[i]; m->xxh->pat++; m->xxh->trk = m->xxh->chn * m->xxh->pat; strncpy(m->name, (char *)ih.title, 20); sprintf(m->type, "IMS (Images Music System)"); MODULE_INFO(); INSTRUMENT_INIT(); for (i = 0; i < m->xxh->ins; i++) { m->xxi[i] = calloc (sizeof (struct xxm_instrument), 1); m->xxs[i].len = 2 * ih.ins[i].size; m->xxs[i].lpe = m->xxs[i].lps + 2 * ih.ins[i].loop_size; m->xxs[i].flg = ih.ins[i].loop_size > 1 ? WAVE_LOOPING : 0; m->xxi[i][0].fin = 0; /* ih.ins[i].finetune; */ m->xxi[i][0].vol = ih.ins[i].volume; m->xxi[i][0].pan = 0x80; m->xxi[i][0].sid = i; m->xxih[i].nsm = !!(m->xxs[i].len); m->xxih[i].rls = 0xfff; copy_adjust(m->xxih[i].name, ih.ins[i].name, 20); if (V(1) && (strlen((char *) m->xxih[i].name) || (m->xxs[i].len > 2))) { report ("[%2X] %-20.20s %04x %04x %04x %c V%02x %+d\n", i, m->xxih[i].name, m->xxs[i].len, m->xxs[i].lps, m->xxs[i].lpe, ih.ins[i].loop_size > 1 ? 'L' : ' ', m->xxi[i][0].vol, m->xxi[i][0].fin >> 4); } }
static int ptm_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int c, r, i, smp_ofs[256]; struct xmp_event *event; struct ptm_file_header pfh; struct ptm_instrument_header pih; uint8 n, b; LOAD_INIT(); /* Load and convert header */ hio_read(&pfh.name, 28, 1, f); /* Song name */ pfh.doseof = hio_read8(f); /* 0x1a */ pfh.vermin = hio_read8(f); /* Minor version */ pfh.vermaj = hio_read8(f); /* Major type */ pfh.rsvd1 = hio_read8(f); /* Reserved */ pfh.ordnum = hio_read16l(f); /* Number of orders (must be even) */ pfh.insnum = hio_read16l(f); /* Number of instruments */ pfh.patnum = hio_read16l(f); /* Number of patterns */ pfh.chnnum = hio_read16l(f); /* Number of channels */ pfh.flags = hio_read16l(f); /* Flags (set to 0) */ pfh.rsvd2 = hio_read16l(f); /* Reserved */ pfh.magic = hio_read32b(f); /* 'PTMF' */ if (pfh.magic != MAGIC_PTMF) return -1; /* Sanity check */ if (pfh.ordnum > 256 || pfh.insnum > 255 || pfh.patnum > 128 || pfh.chnnum > 32) { return -1; } hio_read(&pfh.rsvd3, 16, 1, f); /* Reserved */ hio_read(&pfh.chset, 32, 1, f); /* Channel settings */ hio_read(&pfh.order, 256, 1, f); /* Orders */ for (i = 0; i < 128; i++) pfh.patseg[i] = hio_read16l(f); mod->len = pfh.ordnum; mod->ins = pfh.insnum; mod->pat = pfh.patnum; mod->chn = pfh.chnnum; mod->trk = mod->pat * mod->chn; mod->smp = mod->ins; mod->spd = 6; mod->bpm = 125; memcpy (mod->xxo, pfh.order, 256); m->c4rate = C4_NTSC_RATE; copy_adjust(mod->name, pfh.name, 28); set_type(m, "Poly Tracker PTM %d.%02x", pfh.vermaj, pfh.vermin); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { struct xmp_instrument *xxi = &mod->xxi[i]; struct xmp_sample *xxs = &mod->xxs[i]; struct xmp_subinstrument *sub; pih.type = hio_read8(f); /* Sample type */ hio_read(&pih.dosname, 12, 1, f); /* DOS file name */ pih.vol = hio_read8(f); /* Volume */ pih.c4spd = hio_read16l(f); /* C4 speed */ pih.smpseg = hio_read16l(f); /* Sample segment (not used) */ pih.smpofs = hio_read32l(f); /* Sample offset */ pih.length = hio_read32l(f); /* Length */ pih.loopbeg = hio_read32l(f); /* Loop begin */ pih.loopend = hio_read32l(f); /* Loop end */ pih.gusbeg = hio_read32l(f); /* GUS begin address */ pih.guslps = hio_read32l(f); /* GUS loop start address */ pih.guslpe = hio_read32l(f); /* GUS loop end address */ pih.gusflg = hio_read8(f); /* GUS loop flags */ pih.rsvd1 = hio_read8(f); /* Reserved */ hio_read(&pih.name, 28, 1, f); /* Instrument name */ pih.magic = hio_read32b(f); /* 'PTMS' */ if ((pih.type & 3) != 1) continue; if (subinstrument_alloc(mod, i, 1) < 0) return -1; sub = &xxi->sub[0]; smp_ofs[i] = pih.smpofs; xxs->len = pih.length; xxs->lps = pih.loopbeg; xxs->lpe = pih.loopend; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; xxs->flg = 0; if (pih.type & 0x04) { xxs->flg |= XMP_SAMPLE_LOOP; } if (pih.type & 0x08) { xxs->flg |= XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR; } if (pih.type & 0x10) { xxs->flg |= XMP_SAMPLE_16BIT; xxs->len >>= 1; xxs->lps >>= 1; xxs->lpe >>= 1; } sub->vol = pih.vol; sub->pan = 0x80; sub->sid = i; pih.magic = 0; instrument_name(mod, i, pih.name, 28); D_(D_INFO "[%2X] %-28.28s %05x%c%05x %05x %c V%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, pih.type & 0x10 ? '+' : ' ', xxs->lps, xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ', sub->vol, pih.c4spd); /* Convert C4SPD to relnote/finetune */ c2spd_to_note(pih.c4spd, &sub->xpo, &sub->fin); }
static int s3m_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int c, r, i; struct xmp_event *event = 0, dummy; struct s3m_file_header sfh; struct s3m_instrument_header sih; #ifndef LIBXMP_CORE_PLAYER struct s3m_adlib_header sah; char tracker_name[40]; int quirk87 = 0; #endif int pat_len; uint8 n, b, x8; uint16 *pp_ins; /* Parapointers to instruments */ uint16 *pp_pat; /* Parapointers to patterns */ int ret; LOAD_INIT(); hio_read(&sfh.name, 28, 1, f); /* Song name */ hio_read8(f); /* 0x1a */ sfh.type = hio_read8(f); /* File type */ hio_read16l(f); /* Reserved */ sfh.ordnum = hio_read16l(f); /* Number of orders (must be even) */ sfh.insnum = hio_read16l(f); /* Number of instruments */ sfh.patnum = hio_read16l(f); /* Number of patterns */ sfh.flags = hio_read16l(f); /* Flags */ sfh.version = hio_read16l(f); /* Tracker ID and version */ sfh.ffi = hio_read16l(f); /* File format information */ /* Sanity check */ if (sfh.ffi != 1 && sfh.ffi != 2) { goto err; } if (sfh.ordnum > 255 || sfh.insnum > 255 || sfh.patnum > 255) { goto err; } sfh.magic = hio_read32b(f); /* 'SCRM' */ sfh.gv = hio_read8(f); /* Global volume */ sfh.is = hio_read8(f); /* Initial speed */ sfh.it = hio_read8(f); /* Initial tempo */ sfh.mv = hio_read8(f); /* Master volume */ sfh.uc = hio_read8(f); /* Ultra click removal */ sfh.dp = hio_read8(f); /* Default pan positions if 0xfc */ hio_read32l(f); /* Reserved */ hio_read32l(f); /* Reserved */ sfh.special = hio_read16l(f); /* Ptr to special custom data */ hio_read(sfh.chset, 32, 1, f); /* Channel settings */ #if 0 if (sfh.magic != MAGIC_SCRM) return -1; #endif #ifndef LIBXMP_CORE_PLAYER /* S3M anomaly in return_of_litmus.s3m */ if (sfh.version == 0x1301 && sfh.name[27] == 0x87) quirk87 = 1; if (quirk87) { fix87(sfh.name); fix87(sfh.patnum); fix87(sfh.flags); } #endif copy_adjust(mod->name, sfh.name, 28); pp_ins = calloc(2, sfh.insnum); if (pp_ins == NULL) goto err; pp_pat = calloc (2, sfh.patnum); if (pp_pat == NULL) goto err2; if (sfh.flags & S3M_AMIGA_RANGE) m->quirk |= QUIRK_MODRNG; if (sfh.flags & S3M_ST300_VOLS) m->quirk |= QUIRK_VSALL; /* m->volbase = 4096 / sfh.gv; */ mod->spd = sfh.is; mod->bpm = sfh.it; mod->chn = 0; for (i = 0; i < 32; i++) { if (sfh.chset[i] == S3M_CH_OFF) continue; mod->chn = i + 1; if (sfh.mv & 0x80) { /* stereo */ int x = sfh.chset[i] & S3M_CH_PAN; mod->xxc[i].pan = (x & 0x0f) < 8 ? 0x30 : 0xc0; } else { mod->xxc[i].pan = 0x80; } } if (sfh.ordnum <= XMP_MAX_MOD_LENGTH) { mod->len = sfh.ordnum; hio_read(mod->xxo, 1, mod->len, f); } else { mod->len = XMP_MAX_MOD_LENGTH; hio_read(mod->xxo, 1, mod->len, f); hio_seek(f, sfh.ordnum - XMP_MAX_MOD_LENGTH, SEEK_CUR); } mod->pat = -1; for (i = 0; i < mod->len && mod->xxo[i] < 0xff; ++i) { if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; if (mod->pat > sfh.patnum) mod->pat = sfh.patnum; if (mod->pat == 0) goto err3; mod->trk = mod->pat * mod->chn; /* Load and convert header */ mod->ins = sfh.insnum; mod->smp = mod->ins; for (i = 0; i < sfh.insnum; i++) pp_ins[i] = hio_read16l(f); for (i = 0; i < sfh.patnum; i++) pp_pat[i] = hio_read16l(f); /* Default pan positions */ for (i = 0, sfh.dp -= 0xfc; !sfh.dp /* && n */ && (i < 32); i++) { uint8 x = hio_read8(f); if (x & S3M_PAN_SET) mod->xxc[i].pan = (x << 4) & 0xff; else mod->xxc[i].pan = sfh.mv % 0x80 ? 0x30 + 0xa0 * (i & 1) : 0x80; } m->c4rate = C4_NTSC_RATE; if (sfh.version == 0x1300) m->quirk |= QUIRK_VSALL; #ifndef LIBXMP_CORE_PLAYER switch (sfh.version >> 12) { case 1: snprintf(tracker_name, 40, "Scream Tracker %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); m->quirk |= QUIRK_ST3GVOL; break; case 2: snprintf(tracker_name, 40, "Imago Orpheus %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); break; case 3: if (sfh.version == 0x3216) { strcpy(tracker_name, "Impulse Tracker 2.14v3"); } else if (sfh.version == 0x3217) { strcpy(tracker_name, "Impulse Tracker 2.14v5"); } else { snprintf(tracker_name, 40, "Impulse Tracker %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); } break; case 5: snprintf(tracker_name, 40, "OpenMPT %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); break; case 4: if (sfh.version != 0x4100) { snprintf(tracker_name, 40, "Schism Tracker %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); break; } /* fall through */ case 6: snprintf(tracker_name, 40, "BeRoTracker %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); break; default: snprintf(tracker_name, 40, "unknown (%04x)", sfh.version); }
static int dtt_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, k; int n; uint8 buf[100]; uint32 flags; uint32 pofs[256]; uint8 plen[256]; int sdata[64]; LOAD_INIT(); read32b(f); strcpy(m->type, "Desktop Tracker"); fread(buf, 1, 64, f); strncpy(m->name, (char *)buf, XMP_NAMESIZE); fread(buf, 1, 64, f); strncpy(m->author, (char *)buf, XMP_NAMESIZE); flags = read32l(f); m->xxh->chn = read32l(f); m->xxh->len = read32l(f); fread(buf, 1, 8, f); m->xxh->tpo = read32l(f); m->xxh->rst = read32l(f); m->xxh->pat = read32l(f); m->xxh->ins = m->xxh->smp = read32l(f); m->xxh->trk = m->xxh->pat * m->xxh->chn; fread(m->xxo, 1, (m->xxh->len + 3) & ~3L, f); MODULE_INFO(); for (i = 0; i < m->xxh->pat; i++) { int x = read32l(f); if (i < 256) pofs[i] = x; } n = (m->xxh->pat + 3) & ~3L; for (i = 0; i < n; i++) { int x = read8(f); if (i < 256) plen[i] = x; } INSTRUMENT_INIT(); /* Read instrument names */ reportv(ctx, 1, " Name Len LBeg LEnd L Vol\n"); for (i = 0; i < m->xxh->ins; i++) { int c2spd, looplen; m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1); read8(f); /* note */ m->xxi[i][0].vol = read8(f) >> 1; m->xxi[i][0].pan = 0x80; read16l(f); /* not used */ c2spd = read32l(f); /* period? */ read32l(f); /* sustain start */ read32l(f); /* sustain length */ m->xxs[i].lps = read32l(f); looplen = read32l(f); m->xxs[i].flg = looplen > 0 ? WAVE_LOOPING : 0; m->xxs[i].lpe = m->xxs[i].lps + looplen; m->xxs[i].len = read32l(f); fread(buf, 1, 32, f); copy_adjust(m->xxih[i].name, (uint8 *)buf, 32); sdata[i] = read32l(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\n", 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, c2spd); } } PATTERN_INIT(); /* Read and convert patterns */ reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat); for (i = 0; i < m->xxh->pat; i++) { PATTERN_ALLOC(i); m->xxp[i]->rows = plen[i]; TRACK_ALLOC(i); fseek(f, start + pofs[i], SEEK_SET); for (j = 0; j < m->xxp[i]->rows; j++) { for (k = 0; k < m->xxh->chn; k++) { uint32 x; event = &EVENT (i, k, j); x = read32l(f); event->ins = (x & 0x0000003f); event->note = (x & 0x00000fc0) >> 6; event->fxt = (x & 0x0001f000) >> 12; if (event->note) event->note += 36; /* sorry, we only have room for two effects */ if (x & (0x1f << 17)) { event->f2p = (x & 0x003e0000) >> 17; x = read32l(f); event->fxp = (x & 0x000000ff); event->f2p = (x & 0x0000ff00) >> 8; } else { event->fxp = (x & 0xfc000000) >> 18; } } }
char *instrument_name(struct xmp_module *mod, int i, uint8 *r, int n) { CLAMP(n, 0, 31); return copy_adjust(mod->xxi[i].name, r, n); }
static int mod_load(struct module_data *m, FILE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; int smp_size, pat_size, wow, ptsong = 0; struct xmp_event *event; struct mod_header mh; uint8 mod_event[4]; char *x, pathname[PATH_MAX] = "", *tracker = ""; int detected = 0; char magic[8], idbuffer[32]; int ptkloop = 0; /* Protracker loop */ LOAD_INIT(); mod->ins = 31; mod->smp = mod->ins; mod->chn = 0; smp_size = 0; pat_size = 0; m->quirk |= QUIRK_MODRNG; fread(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { fread(&mh.ins[i].name, 22, 1, f); /* Instrument name */ mh.ins[i].size = read16b(f); /* Length in 16-bit words */ mh.ins[i].finetune = read8(f); /* Finetune (signed nibble) */ mh.ins[i].volume = read8(f); /* Linear playback volume */ mh.ins[i].loop_start = read16b(f); /* Loop start in 16-bit words */ mh.ins[i].loop_size = read16b(f); /* Loop size in 16-bit words */ smp_size += 2 * mh.ins[i].size; } mh.len = read8(f); mh.restart = read8(f); fread(&mh.order, 128, 1, f); memset(magic, 0, 8); fread(magic, 4, 1, f); for (i = 0; mod_magic[i].ch; i++) { if (!(strncmp (magic, mod_magic[i].magic, 4))) { mod->chn = mod_magic[i].ch; tracker = mod_magic[i].tracker; detected = mod_magic[i].flag; ptkloop = mod_magic[i].ptkloop; break; } } if (!mod->chn) { if (!strncmp(magic + 2, "CH", 2) && isdigit(magic[0]) && isdigit(magic[1])) { if ((mod->chn = (*magic - '0') * 10 + magic[1] - '0') > 32) return -1; } else if (!strncmp(magic + 1, "CHN", 3) && isdigit(*magic)) { if (!(mod->chn = (*magic - '0'))) return -1; } else return -1; tracker = "TakeTracker/FastTracker II"; detected = 1; m->quirk &= ~QUIRK_MODRNG; } strncpy (mod->name, (char *) mh.name, 20); mod->len = mh.len; /* mod->rst = mh.restart; */ if (mod->rst >= mod->len) mod->rst = 0; memcpy(mod->xxo, mh.order, 128); for (i = 0; i < 128; i++) { /* This fixes dragnet.mod (garbage in the order list) */ if (mod->xxo[i] > 0x7f) break; if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; pat_size = 256 * mod->chn * mod->pat; INSTRUMENT_INIT(); for (i = 0; i < mod->ins; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); mod->xxs[i].len = 2 * mh.ins[i].size; mod->xxs[i].lps = 2 * mh.ins[i].loop_start; mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size; if (mod->xxs[i].lpe > mod->xxs[i].len) mod->xxs[i].lpe = mod->xxs[i].len; mod->xxs[i].flg = (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe > 8) ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4); mod->xxi[i].sub[0].vol = mh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxi[i].nsm = !!(mod->xxs[i].len); copy_adjust(mod->xxi[i].name, mh.ins[i].name, 22); } /* * Experimental tracker-detection routine */ if (detected) goto skip_test; /* Test for Flextrax modules * * FlexTrax is a soundtracker for Atari Falcon030 compatible computers. * FlexTrax supports the standard MOD file format (up to eight channels) * for compatibility reasons but also features a new enhanced module * format FLX. The FLX format is an extended version of the standard * MOD file format with support for real-time sound effects like reverb * and delay. */ if (0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size < m->size) { int pos = ftell(f); fseek(f, start + 0x43c + mod->pat * 4 * mod->chn * 0x40 + smp_size, SEEK_SET); fread(idbuffer, 1, 4, f); fseek(f, start + pos, SEEK_SET); if (!memcmp(idbuffer, "FLEX", 4)) { tracker = "Flextrax"; ptkloop = 0; goto skip_test; } } /* Test for Mod's Grave WOW modules * * Stefan Danes <*****@*****.**> said: * This weird format is identical to '8CHN' but still uses the 'M.K.' ID. * You can only test for WOW by calculating the size of the module for 8 * channels and comparing this to the actual module length. If it's equal, * the module is an 8 channel WOW. */ if ((wow = (!strncmp(magic, "M.K.", 4) && (0x43c + mod->pat * 32 * 0x40 + smp_size == m->size)))) { mod->chn = 8; tracker = "Mod's Grave"; ptkloop = 0; goto skip_test; } /* Test for Protracker song files */ else if ((ptsong = (!strncmp((char *)magic, "M.K.", 4) && (0x43c + mod->pat * 0x400 == m->size)))) { tracker = "Protracker"; goto skip_test; } /* Test Protracker-like files */ if (mod->chn == 4 && mh.restart == mod->pat) { tracker = "Soundtracker"; } else if (mod->chn == 4 && mh.restart == 0x78) { tracker = "Noisetracker" /*" (0x78)"*/; ptkloop = 1; } else if (mh.restart < 0x7f) { if (mod->chn == 4) { tracker = "Noisetracker"; ptkloop = 1; } else { tracker = "unknown tracker"; ptkloop = 0; } mod->rst = mh.restart; } if (mod->chn != 4 && mh.restart == 0x7f) { tracker = "Scream Tracker 3 MOD"; ptkloop = 0; m->quirk &= ~QUIRK_MODRNG; m->read_event_type = READ_EVENT_ST3; } if (mod->chn == 4 && mh.restart == 0x7f) { for (i = 0; i < 31; i++) { if (mh.ins[i].loop_size == 0) break; } if (i < 31) { tracker = "Protracker clone"; ptkloop = 0; } } if (mh.restart != 0x78 && mh.restart < 0x7f) { for (i = 0; i < 31; i++) { if (mh.ins[i].loop_size == 0) break; } if (i == 31) { /* All loops are size 2 or greater */ for (i = 0; i < 31; i++) { if (mh.ins[i].size == 1 && mh.ins[i].volume == 0) { tracker = "Probably converted"; ptkloop = 0; goto skip_test; } } for (i = 0; i < 31; i++) { if (is_st_ins((char *)mh.ins[i].name)) break; } if (i == 31) { /* No st- instruments */ for (i = 0; i < 31; i++) { if (mh.ins[i].size == 0 && mh.ins[i].loop_size == 1) { switch (mod->chn) { case 4: tracker = "Noisetracker"; /* or Octalyzer */ break; case 6: case 8: tracker = "Octalyser"; ptkloop = 0; break; default: tracker = "unknown tracker"; ptkloop = 0; } goto skip_test; } } if (mod->chn == 4) { tracker = "Protracker"; printf("asd\n"); } else if (mod->chn == 6 || mod->chn == 8) { tracker = "FastTracker 1.01?"; ptkloop = 0; m->quirk &= ~QUIRK_MODRNG; } else { tracker = "unknown tracker"; ptkloop = 0; } } } else { /* Has loops with 0 size */ for (i = 15; i < 31; i++) { if (strlen((char *)mh.ins[i].name) || mh.ins[i].size > 0) break; } if (i == 31 && is_st_ins((char *)mh.ins[14].name)) { tracker = "converted 15 instrument"; ptkloop = 0; goto skip_test; } /* Assume that Fast Tracker modules won't have ST- instruments */ for (i = 0; i < 31; i++) { if (is_st_ins((char *)mh.ins[i].name)) break; } if (i < 31) { tracker = "unknown/converted"; ptkloop = 0; goto skip_test; } if (mod->chn == 4 || mod->chn == 6 || mod->chn == 8) { tracker = "Fast Tracker"; ptkloop = 0; m->quirk &= ~QUIRK_MODRNG; goto skip_test; } tracker = "unknown tracker"; /* ??!? */ ptkloop = 0; } } skip_test: mod->trk = mod->chn * mod->pat; snprintf(mod->type, XMP_NAME_SIZE, "%s (%s)", tracker, magic); MODULE_INFO(); for (i = 0; i < mod->ins; i++) { D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d %c\n", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, (mh.ins[i].loop_size > 1 && mod->xxs[i].lpe > 8) ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4, ptkloop && mod->xxs[i].lps == 0 && mh.ins[i].loop_size > 1 && mod->xxs[i].len > mod->xxs[i].lpe ? '!' : ' '); } PATTERN_INIT(); /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { PATTERN_ALLOC (i); mod->xxp[i]->rows = 64; TRACK_ALLOC (i); for (j = 0; j < (64 * mod->chn); j++) { event = &EVENT (i, j % mod->chn, j / mod->chn); fread (mod_event, 1, 4, f); cvt_pt_event(event, mod_event); } } /* Load samples */ if ((x = strrchr(m->filename, '/'))) strncpy(pathname, m->filename, x - m->filename); D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->smp; i++) { int flags; if (!mod->xxs[i].len) continue; flags = ptkloop ? SAMPLE_FLAG_FULLREP : 0; if (ptsong) { FILE *s; char sn[256]; snprintf(sn, XMP_NAME_SIZE, "%s%s", pathname, mod->xxi[i].name); if ((s = fopen (sn, "rb"))) { load_sample(s, flags, &mod->xxs[mod->xxi[i].sub[0].sid], NULL); } } else { load_sample(f, flags, &mod->xxs[mod->xxi[i].sub[0].sid], NULL); } } if (mod->chn > 4) { m->quirk &= ~QUIRK_MODRNG; m->quirk |= QUIRKS_FT2; m->read_event_type = READ_EVENT_FT2; } else if (strcmp(tracker, "Protracker") == 0) { m->quirk |= QUIRK_INVLOOP; } 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 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 s3m_load(struct module_data *m, FILE *f, const int start) { struct xmp_module *mod = &m->mod; int c, r, i; struct s3m_adlib_header sah; struct xmp_event *event = 0, dummy; struct s3m_file_header sfh; struct s3m_instrument_header sih; int pat_len; uint8 n, b, x8; char tracker_name[40]; int quirk87 = 0; uint16 *pp_ins; /* Parapointers to instruments */ uint16 *pp_pat; /* Parapointers to patterns */ uint8 arpeggio_val[32]; LOAD_INIT(); fread(&sfh.name, 28, 1, f); /* Song name */ read8(f); /* 0x1a */ sfh.type = read8(f); /* File type */ read16l(f); /* Reserved */ sfh.ordnum = read16l(f); /* Number of orders (must be even) */ sfh.insnum = read16l(f); /* Number of instruments */ sfh.patnum = read16l(f); /* Number of patterns */ sfh.flags = read16l(f); /* Flags */ sfh.version = read16l(f); /* Tracker ID and version */ sfh.ffi = read16l(f); /* File format information */ sfh.magic = read32b(f); /* 'SCRM' */ sfh.gv = read8(f); /* Global volume */ sfh.is = read8(f); /* Initial speed */ sfh.it = read8(f); /* Initial tempo */ sfh.mv = read8(f); /* Master volume */ sfh.uc = read8(f); /* Ultra click removal */ sfh.dp = read8(f); /* Default pan positions if 0xfc */ read32l(f); /* Reserved */ read32l(f); /* Reserved */ sfh.special = read16l(f); /* Ptr to special custom data */ fread(sfh.chset, 32, 1, f); /* Channel settings */ #if 0 if (sfh.magic != MAGIC_SCRM) return -1; #endif /* S3M anomaly in return_of_litmus.s3m */ if (sfh.version == 0x1301 && sfh.name[27] == 0x87) quirk87 = 1; if (quirk87) { fix87(sfh.name); fix87(sfh.patnum); fix87(sfh.flags); } copy_adjust(mod->name, sfh.name, 28); /* Load and convert header */ mod->len = sfh.ordnum; mod->ins = sfh.insnum; mod->smp = mod->ins; mod->pat = sfh.patnum; pp_ins = calloc (2, mod->ins); pp_pat = calloc (2, mod->pat); if (sfh.flags & S3M_AMIGA_RANGE) m->quirk |= QUIRK_MODRNG; if (sfh.flags & S3M_ST300_VOLS) m->quirk |= QUIRK_VSALL; /* m->volbase = 4096 / sfh.gv; */ mod->spd = sfh.is; mod->bpm = sfh.it; for (i = 0; i < 32; i++) { if (sfh.chset[i] == S3M_CH_OFF) continue; mod->chn = i + 1; if (sfh.mv & 0x80) { /* stereo */ int x = sfh.chset[i] & S3M_CH_PAN; mod->xxc[i].pan = (x & 0x0f) < 8 ? 0x00 : 0xff; } else { mod->xxc[i].pan = 0x80; } } mod->trk = mod->pat * mod->chn; fread(mod->xxo, 1, mod->len, f); for (i = 0; i < mod->ins; i++) pp_ins[i] = read16l(f); for (i = 0; i < mod->pat; i++) pp_pat[i] = read16l(f); /* Default pan positions */ for (i = 0, sfh.dp -= 0xfc; !sfh.dp /* && n */ && (i < 32); i++) { uint8 x = read8(f); if (x & S3M_PAN_SET) mod->xxc[i].pan = (x << 4) & 0xff; else mod->xxc[i].pan = sfh.mv % 0x80 ? 0x30 + 0xa0 * (i & 1) : 0x80; } m->c4rate = C4_NTSC_RATE; if (sfh.version == 0x1300) m->quirk |= QUIRK_VSALL; switch (sfh.version >> 12) { case 1: snprintf(tracker_name, 40, "Scream Tracker %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); m->quirk |= QUIRK_ST3GVOL; break; case 2: snprintf(tracker_name, 40, "Imago Orpheus %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); break; case 3: if (sfh.version == 0x3216) { strcpy(tracker_name, "Impulse Tracker 2.14v3"); } else if (sfh.version == 0x3217) { strcpy(tracker_name, "Impulse Tracker 2.14v5"); } else { snprintf(tracker_name, 40, "Impulse Tracker %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); } break; case 4: snprintf(tracker_name, 40, "Schism Tracker %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); break; case 5: snprintf(tracker_name, 40, "OpenMPT %d.%02x", (sfh.version & 0x0f00) >> 8, sfh.version & 0xff); break; default: snprintf(tracker_name, 40, "unknown (%04x)", sfh.version); } snprintf(mod->type, XMP_NAME_SIZE, "%s S3M", tracker_name); MODULE_INFO(); PATTERN_INIT(); /* Read patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); memset (arpeggio_val, 0, 32); for (i = 0; i < mod->pat; i++) { PATTERN_ALLOC (i); mod->xxp[i]->rows = 64; TRACK_ALLOC (i); if (!pp_pat[i]) continue; fseek(f, start + pp_pat[i] * 16, SEEK_SET); r = 0; pat_len = read16l(f) - 2; /* Used to be (--pat_len >= 0). Replaced by Rudolf Cejka * <*****@*****.**>, fixes hunt.s3m * ftp://us.aminet.net/pub/aminet/mods/8voic/s3m_hunt.lha */ while (r < mod->xxp[i]->rows) { b = read8(f); if (b == S3M_EOR) { r++; continue; } c = b & S3M_CH_MASK; event = c >= mod->chn ? &dummy : &EVENT (i, c, r); if (b & S3M_NI_FOLLOW) { switch(n = read8(f)) { case 255: n = 0; break; /* Empty note */ case 254: n = XMP_KEY_OFF; break; /* Key off */ default: n = 13 + 12 * MSN (n) + LSN (n); } event->note = n; event->ins = read8(f); pat_len -= 2; } if (b & S3M_VOL_FOLLOWS) { event->vol = read8(f) + 1; pat_len--; } if (b & S3M_FX_FOLLOWS) { event->fxt = read8(f); event->fxp = read8(f); xlat_fx(c, event, arpeggio_val); pat_len -= 2; } } } D_(D_INFO "Stereo enabled: %s", sfh.mv & 0x80 ? "yes" : "no"); D_(D_INFO "Pan settings: %s", sfh.dp ? "no" : "yes"); INSTRUMENT_INIT(); /* Read and convert instruments and samples */ D_(D_INFO "Instruments: %d", mod->ins); for (i = 0; i < mod->ins; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); fseek(f, start + pp_ins[i] * 16, SEEK_SET); x8 = read8(f); mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; if (x8 >= 2) { /* OPL2 FM instrument */ fread(&sah.dosname, 12, 1, f); /* DOS file name */ fread(&sah.rsvd1, 3, 1, f); /* 0x00 0x00 0x00 */ fread(&sah.reg, 12, 1, f); /* Adlib registers */ sah.vol = read8(f); sah.dsk = read8(f); read16l(f); sah.c2spd = read16l(f); /* C 4 speed */ read16l(f); fread(&sah.rsvd4, 12, 1, f); /* Reserved */ fread(&sah.name, 28, 1, f); /* Instrument name */ sah.magic = read32b(f); /* 'SCRI' */ if (sah.magic != MAGIC_SCRI) { D_(D_CRIT "error: FM instrument magic"); return -2; } sah.magic = 0; copy_adjust(mod->xxi[i].name, sah.name, 28); mod->xxi[i].nsm = 1; mod->xxi[i].sub[0].vol = sah.vol; c2spd_to_note(sah.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxi[i].sub[0].xpo += 12; load_sample(f, SAMPLE_FLAG_ADLIB, &mod->xxs[i], (char *)&sah.reg); D_(D_INFO "[%2X] %-28.28s", i, mod->xxi[i].name); continue; } fread(&sih.dosname, 13, 1, f); /* DOS file name */ sih.memseg = read16l(f); /* Pointer to sample data */ sih.length = read32l(f); /* Length */ sih.loopbeg = read32l(f); /* Loop begin */ sih.loopend = read32l(f); /* Loop end */ sih.vol = read8(f); /* Volume */ sih.rsvd1 = read8(f); /* Reserved */ sih.pack = read8(f); /* Packing type (not used) */ sih.flags = read8(f); /* Loop/stereo/16bit samples flags */ sih.c2spd = read16l(f); /* C 4 speed */ sih.rsvd2 = read16l(f); /* Reserved */ fread(&sih.rsvd3, 4, 1, f); /* Reserved */ sih.int_gp = read16l(f); /* Internal - GUS pointer */ sih.int_512 = read16l(f); /* Internal - SB pointer */ sih.int_last = read32l(f); /* Internal - SB index */ fread(&sih.name, 28, 1, f); /* Instrument name */ sih.magic = read32b(f); /* 'SCRS' */ if (x8 == 1 && sih.magic != MAGIC_SCRS) { D_(D_CRIT "error: instrument magic"); return -2; } if (quirk87) { fix87(sih.length); fix87(sih.loopbeg); fix87(sih.loopend); fix87(sih.flags); } mod->xxs[i].len = sih.length; mod->xxi[i].nsm = sih.length > 0 ? 1 : 0; mod->xxs[i].lps = sih.loopbeg; mod->xxs[i].lpe = sih.loopend; mod->xxs[i].flg = sih.flags & 1 ? XMP_SAMPLE_LOOP : 0; if (sih.flags & 4) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } mod->xxi[i].sub[0].vol = sih.vol; sih.magic = 0; copy_adjust(mod->xxi[i].name, sih.name, 28); D_(D_INFO "[%2X] %-28.28s %04x%c%04x %04x %c V%02x %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].flg & XMP_SAMPLE_16BIT ?'+' : ' ', mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, sih.c2spd); c2spd_to_note(sih.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); fseek(f, start + 16L * sih.memseg, SEEK_SET); load_sample(f, (sfh.ffi - 1) * SAMPLE_FLAG_UNS, &mod->xxs[i], NULL); }
static int ptdt_load(struct module_data *m, FILE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; struct xmp_event *event; struct mod_header mh; uint8 mod_event[4]; fread(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { fread(&mh.ins[i].name, 22, 1, f); mh.ins[i].size = read16b(f); mh.ins[i].finetune = read8(f); mh.ins[i].volume = read8(f); mh.ins[i].loop_start = read16b(f); mh.ins[i].loop_size = read16b(f); } mh.len = read8(f); mh.restart = read8(f); fread(&mh.order, 128, 1, f); fread(&mh.magic, 4, 1, f); mod->ins = 31; mod->smp = mod->ins; mod->chn = 4; mod->len = mh.len; mod->rst = mh.restart; memcpy(mod->xxo, mh.order, 128); for (i = 0; i < 128; i++) { if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; mod->trk = mod->chn * mod->pat; INSTRUMENT_INIT(); for (i = 0; i < mod->ins; i++) { mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); mod->xxs[i].len = 2 * mh.ins[i].size; mod->xxs[i].lps = 2 * mh.ins[i].loop_start; mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size; mod->xxs[i].flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4); mod->xxi[i].sub[0].vol = mh.ins[i].volume; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxi[i].nsm = !!(mod->xxs[i].len); mod->xxi[i].rls = 0xfff; copy_adjust(mod->xxi[i].name, mh.ins[i].name, 22); D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mh.ins[i].loop_size > 1 ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4); } PATTERN_INIT(); /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { PATTERN_ALLOC(i); mod->xxp[i]->rows = 64; TRACK_ALLOC(i); for (j = 0; j < (64 * 4); j++) { event = &EVENT(i, j % 4, j / 4); fread(mod_event, 1, 4, f); cvt_pt_event(event, mod_event); } } m->quirk |= QUIRK_MODRNG; /* Load samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->smp; i++) { if (!mod->xxs[i].len) continue; load_sample(f, 0, &mod->xxs[mod->xxi[i].sub[0].sid], NULL); } return 0; }
static int dtt_load(struct module_data *m, xmp_file f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j, k; int n; uint8 buf[100]; uint32 flags; uint32 pofs[256]; uint8 plen[256]; int sdata[64]; LOAD_INIT(); read32b(f); set_type(m, "Desktop Tracker"); xmp_fread(buf, 1, 64, f); strncpy(mod->name, (char *)buf, XMP_NAME_SIZE); xmp_fread(buf, 1, 64, f); /* strncpy(m->author, (char *)buf, XMP_NAME_SIZE); */ flags = read32l(f); mod->chn = read32l(f); mod->len = read32l(f); xmp_fread(buf, 1, 8, f); mod->spd = read32l(f); mod->rst = read32l(f); mod->pat = read32l(f); mod->ins = mod->smp = read32l(f); mod->trk = mod->pat * mod->chn; xmp_fread(mod->xxo, 1, (mod->len + 3) & ~3L, f); MODULE_INFO(); for (i = 0; i < mod->pat; i++) { int x = read32l(f); if (i < 256) pofs[i] = x; } n = (mod->pat + 3) & ~3L; for (i = 0; i < n; i++) { int x = read8(f); if (i < 256) plen[i] = x; } INSTRUMENT_INIT(); /* Read instrument names */ for (i = 0; i < mod->ins; i++) { int c2spd, looplen; mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1); read8(f); /* note */ mod->xxi[i].sub[0].vol = read8(f) >> 1; mod->xxi[i].sub[0].pan = 0x80; read16l(f); /* not used */ c2spd = read32l(f); /* period? */ read32l(f); /* sustain start */ read32l(f); /* sustain length */ mod->xxs[i].lps = read32l(f); looplen = read32l(f); mod->xxs[i].flg = looplen > 0 ? XMP_SAMPLE_LOOP : 0; mod->xxs[i].lpe = mod->xxs[i].lps + looplen; mod->xxs[i].len = read32l(f); xmp_fread(buf, 1, 32, f); copy_adjust(mod->xxi[i].name, (uint8 *)buf, 32); sdata[i] = read32l(f); mod->xxi[i].nsm = !!(mod->xxs[i].len); mod->xxi[i].sub[0].sid = i; D_(D_INFO "[%2X] %-32.32s %04x %04x %04x %c V%02x %d\n", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, c2spd); } PATTERN_INIT(); /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { PATTERN_ALLOC(i); mod->xxp[i]->rows = plen[i]; TRACK_ALLOC(i); xmp_fseek(f, start + pofs[i], SEEK_SET); for (j = 0; j < mod->xxp[i]->rows; j++) { for (k = 0; k < mod->chn; k++) { uint32 x; event = &EVENT (i, k, j); x = read32l(f); event->ins = (x & 0x0000003f); event->note = (x & 0x00000fc0) >> 6; event->fxt = (x & 0x0001f000) >> 12; if (event->note) event->note += 48; /* sorry, we only have room for two effects */ if (x & (0x1f << 17)) { event->f2p = (x & 0x003e0000) >> 17; x = read32l(f); event->fxp = (x & 0x000000ff); event->f2p = (x & 0x0000ff00) >> 8; } else { event->fxp = (x & 0xfc000000) >> 18; } } }