static int read_abk_song(HIO_HANDLE *f, struct abk_song *song, uint32 songs_section_offset) { int i; uint32 song_section; /* move to the start of the songs data section */ hio_seek(f, songs_section_offset, SEEK_SET); if (hio_read16b(f) != 1) { /* we only support a single song. * in a an abk file for now */ return -1; } song_section = hio_read32b(f); hio_seek(f, songs_section_offset + song_section, SEEK_SET); for (i=0; i<AMOS_ABK_CHANNELS; i++) { song->playlist_offset[i] = hio_read16b(f) + songs_section_offset + song_section; } song->tempo = hio_read16b(f); /* unused. just progress the file pointer forward */ (void) hio_read16b(f); hio_read(song->song_name, 1, AMOS_STRING_LEN, f); return 0; }
/** * @brief read the ABK playlist out from the file stream. This method malloc's some memory for the playlist * and can realloc if the playlist is very long. * @param f the stream to read from * @param playlist_offset the offset to the playlist sections. * @param playlist this structure is populated with the result. */ static void read_abk_playlist(HIO_HANDLE *f, uint32 playlist_offset, struct abk_playlist *playlist) { uint16 playdata; int arraysize; arraysize = 64; /* clear the length */ playlist->length = 0; /* move to the start of the songs data section. */ hio_seek(f, playlist_offset, SEEK_SET); playlist->pattern = (uint16 *) malloc(arraysize * sizeof(uint16)); playdata = hio_read16b(f); while((playdata != 0xFFFF) && (playdata != 0xFFFE)) { /* i hate doing a realloc in a loop but i'd rather not traverse the list twice.*/ if (playlist->length >= arraysize) { arraysize *= 2; playlist->pattern = (uint16 *) realloc(playlist->pattern , arraysize * sizeof(uint16)); } playlist->pattern[playlist->length++] = playdata; playdata = hio_read16b(f); }; }
static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; struct local_data *data = (struct local_data *)parm; mod->chn = hio_read16b(f); data->realpat = hio_read16b(f); mod->trk = mod->chn * mod->pat; return 0; }
static int get_samp(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; struct local_data *data = (struct local_data *)parm; int i, j; int looplen; /* Should be always 36 */ mod->ins = size / 32; /* sizeof(struct okt_instrument_header); */ mod->smp = mod->ins; if (instrument_init(mod) < 0) return -1; for (j = i = 0; i < mod->ins; i++) { struct xmp_instrument *xxi = &mod->xxi[i]; struct xmp_sample *xxs = &mod->xxs[j]; struct xmp_subinstrument *sub; if (subinstrument_alloc(mod, i, 1) < 0) return -1; sub = &xxi->sub[0]; hio_read(xxi->name, 1, 20, f); adjust_string((char *)xxi->name); /* Sample size is always rounded down */ xxs->len = hio_read32b(f) & ~1; xxs->lps = hio_read16b(f); looplen = hio_read16b(f); xxs->lpe = xxs->lps + looplen; xxs->flg = looplen > 2 ? XMP_SAMPLE_LOOP : 0; sub->vol = hio_read16b(f); data->mode[i] = hio_read16b(f); sub->pan = 0x80; sub->sid = j; data->idx[j] = i; if (xxs->len > 0) { xxi->nsm = 1; j++; } } return 0; }
static int dt_test(HIO_HANDLE *f, char *t, const int start) { if (hio_read32b(f) != MAGIC_D_T_) return -1; hio_read32b(f); /* chunk size */ hio_read16b(f); /* type */ hio_read16b(f); /* 0xff then mono */ hio_read16b(f); /* reserved */ hio_read16b(f); /* tempo */ hio_read16b(f); /* bpm */ hio_read32b(f); /* undocumented */ read_title(f, t, 32); return 0; }
static int get_s_q_(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i, maxpat; mod->len = hio_read16b(f); mod->rst = hio_read16b(f); hio_read32b(f); /* reserved */ for (maxpat = i = 0; i < 128; i++) { mod->xxo[i] = hio_read8(f); if (mod->xxo[i] > maxpat) maxpat = mod->xxo[i]; } mod->pat = maxpat + 1; return 0; }
static int get_plen(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; mod->len = hio_read16b(f); D_(D_INFO "Module length: %d", mod->len); return 0; }
static int get_slen(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; mod->pat = hio_read16b(f); mod->trk = mod->pat * mod->chn; return 0; }
static int get_spee(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; mod->spd = hio_read16b(f); mod->bpm = 125; return 0; }
static int get_d_t_(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int b; hio_read16b(f); /* type */ hio_read16b(f); /* 0xff then mono */ hio_read16b(f); /* reserved */ mod->spd = hio_read16b(f); if ((b = hio_read16b(f)) > 0) /* RAMBO.DTM has bpm 0 */ mod->bpm = b; hio_read32b(f); /* undocumented */ hio_read(mod->name, 32, 1, f); set_type(m, "Digital Tracker DTM"); MODULE_INFO(); return 0; }
static int stim_test(HIO_HANDLE *f, char *t, const int start) { if (hio_read32b(f) != MAGIC_STIM) return -1; if (hio_read16b(f) > 16) return -1; read_title(f, t, 0); return 0; }
int mmd_load_hybrid_instrument(HIO_HANDLE *f, struct module_data *m, int i, int smp_idx, struct SynthInstr *synth, struct InstrExt *exp_smp, struct MMD0sample *sample) { struct xmp_module *mod = &m->mod; struct xmp_instrument *xxi = &mod->xxi[i]; struct xmp_subinstrument *sub; struct xmp_sample *xxs; int length, type; int pos = hio_tell(f); synth->defaultdecay = hio_read8(f); hio_seek(f, 3, SEEK_CUR); synth->rep = hio_read16b(f); synth->replen = hio_read16b(f); synth->voltbllen = hio_read16b(f); synth->wftbllen = hio_read16b(f); synth->volspeed = hio_read8(f); synth->wfspeed = hio_read8(f); synth->wforms = hio_read16b(f); hio_read(synth->voltbl, 1, 128, f);; hio_read(synth->wftbl, 1, 128, f);; hio_seek(f, pos - 6 + hio_read32b(f), SEEK_SET); length = hio_read32b(f); type = hio_read16b(f); if (med_new_instrument_extras(xxi) != 0) return -1; xxi->nsm = 1; if (subinstrument_alloc(mod, i, 1) < 0) return -1; MED_INSTRUMENT_EXTRAS((*xxi))->vts = synth->volspeed; MED_INSTRUMENT_EXTRAS((*xxi))->wts = synth->wfspeed; sub = &xxi->sub[0]; sub->pan = 0x80; sub->vol = sample->svol; sub->xpo = sample->strans; sub->sid = smp_idx; sub->fin = exp_smp->finetune; xxs = &mod->xxs[smp_idx]; xxs->len = length; xxs->lps = 2 * sample->rep; xxs->lpe = xxs->lps + 2 * sample->replen; xxs->flg = sample->replen > 1 ? XMP_SAMPLE_LOOP : 0; if (load_sample(m, f, 0, xxs, NULL) < 0) return -1; return 0; }
static int get_cmod(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i, j, k; mod->chn = 0; for (i = 0; i < 4; i++) { j = hio_read16b(f); for (k = ! !j; k >= 0; k--) { mod->chn++; } } return 0; }
static int ssn_test(HIO_HANDLE *f, char *t, const int start) { uint16 id; id = hio_read16b(f); if (id != 0x6966 && id != 0x4a4e) return -1; hio_seek(f, 238, SEEK_CUR); if (hio_read8(f) != 0xff) return -1; hio_seek(f, start + 2, SEEK_SET); read_title(f, t, 36); return 0; }
static int mdl_test(HIO_HANDLE *f, char *t, const int start) { uint16 id; if (hio_read32b(f) != MAGIC_DMDL) return -1; hio_read8(f); /* version */ id = hio_read16b(f); if (id == 0x494e) { /* IN */ hio_read32b(f); read_title(f, t, 32); } else { read_title(f, t, 0); } return 0; }
static int emod_test(HIO_HANDLE * f, char *t, const int start) { if (hio_read32b(f) != MAGIC_FORM) return -1; hio_read32b(f); if (hio_read32b(f) != MAGIC_EMOD) return -1; if (hio_read32b(f) == MAGIC_EMIC) { hio_read32b(f); /* skip size */ hio_read16b(f); /* skip version */ read_title(f, t, 20); } else { read_title(f, t, 0); } return 0; }
static int get_info(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; /* int flags; */ /* int day, month, year, hour, min, sec; int dhour, dmin, dsec; */ hio_read(mod->name, 1, 32, f); mod->ins = hio_read16b(f); mod->len = hio_read16b(f); mod->pat = hio_read16b(f); mod->gvl = hio_read16b(f); mod->bpm = hio_read16b(f); /*flags =*/ hio_read16b(f); /*day =*/ hio_read16b(f); /*month =*/ hio_read16b(f); /*year =*/ hio_read16b(f); /*hour =*/ hio_read16b(f); /*min =*/ hio_read16b(f); /*sec =*/ hio_read16b(f); /*dhour =*/ hio_read16b(f); /*dmin =*/ hio_read16b(f); /*dsec =*/ hio_read16b(f); /* Sanity check */ if (mod->ins > 255 || mod->len > 256 || mod->pat > 255) { return -1; } MODULE_INFO(); /*D_(D_INFO "Creation date: %02d/%02d/%02d %02d:%02d:%02d", day, month, year, hour, min, sec); D_(D_INFO "Playing time: %02d:%02d:%02d", dhour, dmin, dsec);*/ return 0; }
static int mod_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 mod_header mh; uint8 mod_event[4]; char magic[8]; int ptkloop = 0; /* Protracker loop */ LOAD_INIT(); mod->ins = 31; mod->smp = mod->ins; mod->chn = 0; m->quirk |= QUIRK_MODRNG; hio_read(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); /* Instrument name */ mh.ins[i].size = hio_read16b(f); /* Length in 16-bit words */ mh.ins[i].finetune = hio_read8(f); /* Finetune (signed nibble) */ mh.ins[i].volume = hio_read8(f); /* Linear playback volume */ mh.ins[i].loop_start = hio_read16b(f); /* Loop start in 16-bit words */ mh.ins[i].loop_size = hio_read16b(f); /* Loop size in 16-bit words */ } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); memset(magic, 0, 8); hio_read(magic, 4, 1, f); if (!memcmp(magic, "M.K.", 4)) { mod->chn = 4; } else if (!strncmp(magic + 2, "CH", 2) && isdigit((int)magic[0]) && isdigit((int)magic[1])) { mod->chn = (*magic - '0') * 10 + magic[1] - '0'; } else if (!strncmp(magic + 1, "CHN", 3) && isdigit((int)*magic)) { mod->chn = *magic - '0'; } else { return -1; } 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++; if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -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 >= 4) ? 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; instrument_name(mod, i, mh.ins[i].name, 22); if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; } mod->trk = mod->chn * mod->pat; set_type(m, mod->chn == 4 ? "Protracker" : "Fasttracker"); 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 ? '!' : ' '); } if (pattern_init(mod) < 0) return -1; /* Load 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); hio_read (mod_event, 1, 4, f); decode_protracker_event(event, mod_event); } } /* Load samples */ 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 (load_sample(m, f, flags, &mod->xxs[i], NULL) < 0) return -1; } if (mod->chn > 4) { m->quirk &= ~QUIRK_MODRNG; m->quirk |= QUIRKS_FT2; m->read_event_type = READ_EVENT_FT2; } return 0; }
static int depack_pp21(HIO_HANDLE *in, FILE *out) { uint8 ptable[128]; int max = 0; uint8 trk[4][128]; int tptr[512][64]; uint8 numpat; uint8 *tab; uint8 buf[1024]; int i, j; int size; int ssize = 0; int tabsize = 0; /* Reference Table Size */ memset(ptable, 0, 128); memset(trk, 0, 4 * 128); memset(tptr, 0, 512 * 128); pw_write_zero(out, 20); /* title */ for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /* sample name */ write16b(out, size = hio_read16b(in)); ssize += size * 2; write8(out, hio_read8(in)); /* finetune */ write8(out, hio_read8(in)); /* volume */ write16b(out, hio_read16b(in)); /* loop start */ write16b(out, hio_read16b(in)); /* loop size */ } write8(out, numpat = hio_read8(in)); /* number of patterns */ write8(out, hio_read8(in)); /* NoiseTracker restart byte */ max = 0; for (j = 0; j < 4; j++) { for (i = 0; i < 128; i++) { trk[j][i] = hio_read8(in); if (trk[j][i] > max) max = trk[j][i]; } } /* write pattern table without any optimizing ! */ for (i = 0; i < numpat; i++) write8(out, i); pw_write_zero(out, 128 - i); write32b(out, PW_MOD_MAGIC); /* M.K. */ /* PATTERN DATA code starts here */ /*printf ("Highest track number : %d\n", max); */ for (j = 0; j <= max; j++) { for (i = 0; i < 64; i++) tptr[j][i] = hio_read16b(in); } /* read "reference table" size */ tabsize = hio_read32b(in); /* read "reference Table" */ tab = (uint8 *)malloc(tabsize); hio_read(tab, tabsize, 1, in); for (i = 0; i < numpat; i++) { memset(buf, 0, 1024); for (j = 0; j < 64; j++) { uint8 *b = buf + j * 16; memcpy(b, tab + tptr[trk[0][i]][j] * 4, 4); memcpy(b + 4, tab + tptr[trk[1][i]][j] * 4, 4); memcpy(b + 8, tab + tptr[trk[2][i]][j] * 4, 4); memcpy(b + 12, tab + tptr[trk[3][i]][j] * 4, 4); } fwrite (buf, 1024, 1, out); } free (tab); /* Now, it's sample data ... though, VERY quickly handled :) */ pw_move_data(out, in, ssize); return 0; }
static int hmn_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 mod_header mh; struct mupp mupp[31]; uint8 mod_event[4]; int mupp_index, num_mupp; LOAD_INIT(); /* * clr.b $1c(a6) ;prog on/off * CMP.L #'Mupp',-$16(a3,d4.l) * bne.s noprgo * move.l a0,-(a7) * move.b #1,$1c(a6) ;prog on * move.l l697,a0 * lea $43c(a0),a0 * moveq #0,d2 * move.b -$16+$4(a3,d4.l),d2 ;pattno * mulu #$400,d2 * lea (a0,d2.l),a0 * move.l a0,4(a6) ;proginstr data-start * moveq #0,d2 * MOVE.B $3C0(A0),$12(A6) * AND.B #$7F,$12(A6) * move.b $380(a0),d2 * mulu #$20,d2 * lea (a0,d2.w),a0 * move.l a0,$a(a6) ;loopstartmempoi = startmempoi * move.B $3(a3,d4.l),$13(a6) ;volume * move.b -$16+$5(a3,d4.l),8(a6) ;dataloopstart * move.b -$16+$6(a3,d4.l),9(a6) ;dataloopend * move.w #$10,$e(a6) ;looplen * move.l (a7)+,a0 * MOVE.W $12(A6),(A2) * AND.W #$FF,(A2) * BRA.S L505_LQ */ /* * Wavetable structure is 22 * 32 byte waveforms and 32 byte * wave control data with looping. */ memset(mupp, 0, 31 * sizeof (struct mupp)); hio_read(&mh.name, 20, 1, f); num_mupp = 0; for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); /* Instrument name */ if (memcmp(mh.ins[i].name, "Mupp", 4) == 0) { mupp[i].prgon = 1; mupp[i].pattno = mh.ins[i].name[4]; mupp[i].dataloopstart = mh.ins[i].name[5]; mupp[i].dataloopend = mh.ins[i].name[6]; num_mupp++; } mh.ins[i].size = hio_read16b(f); mh.ins[i].finetune = hio_read8(f); mh.ins[i].volume = hio_read8(f); mh.ins[i].loop_start = hio_read16b(f); mh.ins[i].loop_size = hio_read16b(f); } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); hio_read(&mh.magic, 4, 1, f); mod->chn = 4; mod->ins = 31; mod->smp = mod->ins + 28 * num_mupp; 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; if (hmn_new_module_extras(m) != 0) return -1; strncpy(mod->name, (char *)mh.name, 20); set_type(m, "%s (%4.4s)", "His Master's Noise", mh.magic); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (mupp[i].prgon) { mod->xxi[i].nsm = 28; snprintf(mod->xxi[i].name, 32, "Mupp %02x %02x %02x", mupp[i].pattno, mupp[i].dataloopstart, mupp[i].dataloopend); if (hmn_new_instrument_extras(&mod->xxi[i]) != 0) return -1; } else { mod->xxi[i].nsm = 1; instrument_name(mod, i, mh.ins[i].name, 22); 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; } if (subinstrument_alloc(mod, i, mod->xxi[i].nsm) < 0) return -1; for (j = 0; j < mod->xxi[i].nsm; j++) { mod->xxi[i].sub[j].fin = -(int8)(mh.ins[i].finetune << 3); mod->xxi[i].sub[j].vol = mh.ins[i].volume; mod->xxi[i].sub[j].pan = 0x80; mod->xxi[i].sub[j].sid = i; } } if (pattern_init(mod) < 0) return -1; /* Load 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 * 4); j++) { event = &EVENT(i, j % 4, j / 4); hio_read(mod_event, 1, 4, f); decode_protracker_event(event, mod_event); switch (event->fxt) { case 0x07: event->fxt = FX_MEGAARP; break; case 0x08: case 0x09: case 0x0e: event->fxt = event->fxp = 0; break; } } } m->quirk |= QUIRK_MODRNG; /* Load samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < 31; i++) { if (load_sample(m, f, SAMPLE_FLAG_FULLREP, &mod->xxs[i], NULL) < 0) { return -1; } } /* Load Mupp samples */ mupp_index = 0; for (i = 0; i < 31; i ++) { struct hmn_instrument_extras *extra = (struct hmn_instrument_extras *)mod->xxi[i].extra; if (!mupp[i].prgon) continue; hio_seek(f, start + 1084 + 1024 * mupp[i].pattno, SEEK_SET); for (j = 0; j < 28; j++) { int k = 31 + 28 * mupp_index + j; mod->xxi[i].sub[j].sid = k; mod->xxs[k].len = 32; mod->xxs[k].lps = 0; mod->xxs[k].lpe = 32; mod->xxs[k].flg = XMP_SAMPLE_LOOP; if (load_sample(m, f, 0, &mod->xxs[k], NULL) < 0) return -1; } extra->dataloopstart = mupp[i].dataloopstart; extra->dataloopend = mupp[i].dataloopend; hio_read(extra->data, 1, 64, f); hio_read(extra->progvolume, 1, 64, f); mupp_index++; } return 0; }
static int gtk_load(struct module_data *m, HIO_HANDLE *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(); hio_read(buffer, 4, 1, f); ver = buffer[3]; hio_read(mod->name, 32, 1, f); set_type(m, "Graoumf Tracker GTK v%d", ver); hio_seek(f, 160, SEEK_CUR); /* skip comments */ mod->ins = hio_read16b(f); mod->smp = mod->ins; rows = hio_read16b(f); mod->chn = hio_read16b(f); mod->len = hio_read16b(f); mod->rst = hio_read16b(f); m->volbase = 0x100; MODULE_INFO(); D_(D_INFO "Instruments : %d ", mod->ins); if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(buffer, 28, 1, f); instrument_name(mod, i, buffer, 28); if (ver == 1) { hio_read32b(f); mod->xxs[i].len = hio_read32b(f); mod->xxs[i].lps = hio_read32b(f); size = hio_read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + size - 1; hio_read16b(f); hio_read16b(f); mod->xxi[i].sub[0].vol = 0xff; mod->xxi[i].sub[0].pan = 0x80; bits = 1; c2spd = 8363; } else { hio_seek(f, 14, SEEK_CUR); hio_read16b(f); /* autobal */ bits = hio_read16b(f); /* 1 = 8 bits, 2 = 16 bits */ c2spd = hio_read16b(f); c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxs[i].len = hio_read32b(f); mod->xxs[i].lps = hio_read32b(f); size = hio_read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + size - 1; mod->xxi[i].sub[0].vol = hio_read16b(f); hio_read8(f); mod->xxi[i].sub[0].fin = hio_read8s(f); } if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; 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 depack_pru2(HIO_HANDLE *in, FILE *out) { uint8 header[2048]; uint8 npat; uint8 ptable[128]; uint8 max = 0; uint8 v[4][4]; int size, ssize = 0; int i, j; memset(header, 0, 2048); memset(ptable, 0, 128); memset(v, 0, 16); pw_write_zero(out, 20); /* title */ hio_seek(in, 8, SEEK_SET); for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /*sample name */ write16b(out, size = hio_read16b(in)); /* size */ ssize += size * 2; write8(out, hio_read8(in)); /* finetune */ write8(out, hio_read8(in)); /* volume */ write16b(out, hio_read16b(in)); /* loop start */ write16b(out, hio_read16b(in)); /* loop size */ } write8(out, npat = hio_read8(in)); /* number of patterns */ write8(out, hio_read8(in)); /* noisetracker byte */ for (i = 0; i < 128; i++) { uint8 x; write8(out, x = hio_read8(in)); max = (x > max) ? x : max; } write32b(out, PW_MOD_MAGIC); /* pattern data stuff */ hio_seek(in, 770, SEEK_SET); for (i = 0; i <= max; i++) { for (j = 0; j < 256; j++) { uint8 c[4]; memset(c, 0, 4); header[0] = hio_read8(in); if (header[0] == 0x80) { write32b(out, 0); } else if (header[0] == 0xc0) { fwrite(v[0], 4, 1, out); memcpy(c, v[0], 4); } else if (header[0] >= 74) { return -1; } else { header[1] = hio_read8(in); header[2] = hio_read8(in); c[0] = (header[1] & 0x80) >> 3; c[0] |= ptk_table[(header[0] >> 1)][0]; c[1] = ptk_table[(header[0] >> 1)][1]; c[2] = (header[1] & 0x70) << 1; c[2] |= (header[0] & 0x01) << 4; c[2] |= (header[1] & 0x0f); c[3] = header[2]; fwrite(c, 1, 4, out); } /* rol previous values */ memcpy(&v[0], &v[1], 4); memcpy(&v[1], &v[2], 4); memcpy(&v[2], &v[3], 4); memcpy(v[3], c, 4); } } /* sample data */ pw_move_data(out, in, ssize); return 0; }
int mmd_load_synth_instrument(HIO_HANDLE *f, struct module_data *m, int i, int smp_idx, struct SynthInstr *synth, struct InstrExt *exp_smp, struct MMD0sample *sample) { struct xmp_module *mod = &m->mod; struct xmp_instrument *xxi = &mod->xxi[i]; int pos = hio_tell(f); int j; synth->defaultdecay = hio_read8(f); hio_seek(f, 3, SEEK_CUR); synth->rep = hio_read16b(f); synth->replen = hio_read16b(f); synth->voltbllen = hio_read16b(f); synth->wftbllen = hio_read16b(f); synth->volspeed = hio_read8(f); synth->wfspeed = hio_read8(f); synth->wforms = hio_read16b(f); hio_read(synth->voltbl, 1, 128, f);; hio_read(synth->wftbl, 1, 128, f);; for (j = 0; j < 64; j++) synth->wf[j] = hio_read32b(f); D_(D_INFO " VS:%02x WS:%02x WF:%02x %02x %+3d %+1d", synth->volspeed, synth->wfspeed, synth->wforms & 0xff, sample->svol, sample->strans, exp_smp->finetune); if (synth->wforms == 0xffff) return 1; if (synth->wforms > 64) return -1; if (med_new_instrument_extras(&mod->xxi[i]) != 0) return -1; mod->xxi[i].nsm = synth->wforms; if (subinstrument_alloc(mod, i, synth->wforms) < 0) return -1; MED_INSTRUMENT_EXTRAS((*xxi))->vts = synth->volspeed; MED_INSTRUMENT_EXTRAS((*xxi))->wts = synth->wfspeed; for (j = 0; j < synth->wforms; j++) { struct xmp_subinstrument *sub = &xxi->sub[j]; struct xmp_sample *xxs = &mod->xxs[smp_idx]; sub->pan = 0x80; sub->vol = sample->svol; sub->xpo = sample->strans - 24; sub->sid = smp_idx; sub->fin = exp_smp->finetune; hio_seek(f, pos - 6 + synth->wf[j], SEEK_SET); xxs->len = hio_read16b(f) * 2; xxs->lps = 0; xxs->lpe = mod->xxs[smp_idx].len; xxs->flg = XMP_SAMPLE_LOOP; if (load_sample(m, f, 0, xxs, NULL) < 0) return -1; smp_idx++; } return 0; }
static int get_pbod(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; struct local_data *data = (struct local_data *)parm; struct xmp_event *e; uint16 rows; int j; if (data->pattern >= mod->pat) return 0; if (!data->pattern) { if (pattern_init(mod) < 0) return -1; D_(D_INFO "Stored patterns: %d", mod->pat); } rows = hio_read16b(f); if (pattern_tracks_alloc(mod, data->pattern, rows) < 0) return -1; for (j = 0; j < rows * mod->chn; j++) { uint8 note, ins; e = &EVENT(data->pattern, j % mod->chn, j / mod->chn); memset(e, 0, sizeof(struct xmp_event)); note = hio_read8(f); ins = hio_read8(f); if (note) { e->note = 48 + note; e->ins = 1 + ins; } e->fxt = fx[hio_read8(f)]; e->fxp = hio_read8(f); if ((e->fxt == FX_VOLSET) && (e->fxp > 0x40)) { if (e->fxp <= 0x50) { e->fxt = FX_VOLSLIDE; e->fxp -= 0x40; } else if (e->fxp <= 0x60) { e->fxt = FX_VOLSLIDE; e->fxp = (e->fxp - 0x50) << 4; } else if (e->fxp <= 0x70) { e->fxt = FX_F_VSLIDE_DN; e->fxp = e->fxp - 0x60; } else if (e->fxp <= 0x80) { e->fxt = FX_F_VSLIDE_UP; e->fxp = e->fxp - 0x70; } } if (e->fxt == FX_ARPEGGIO) /* Arpeggio fixup */ e->fxp = (((24 - MSN(e->fxp)) % 12) << 4) | LSN(e->fxp); if (e->fxt == NONE) e->fxt = e->fxp = 0; } data->pattern++; return 0; }
static int med3_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j; uint32 mask; int transp, sliding; LOAD_INIT(); hio_read32b(f); set_type(m, "MED 2.00 MED3"); mod->ins = mod->smp = 32; if (instrument_init(mod) < 0) return -1; /* read instrument names */ for (i = 0; i < 32; i++) { uint8 c, buf[40]; for (j = 0; j < 40; j++) { c = hio_read8(f); buf[j] = c; if (c == 0) break; } instrument_name(mod, i, buf, 32); if (subinstrument_alloc(mod, i, 1) < 0) return -1; } /* read instrument volumes */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { mod->xxi[i].sub[0].vol = mask & MASK ? hio_read8(f) : 0; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].fin = 0; mod->xxi[i].sub[0].sid = i; } /* read instrument loops */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { mod->xxs[i].lps = mask & MASK ? hio_read16b(f) : 0; } /* read instrument loop length */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { uint32 lsiz = mask & MASK ? hio_read16b(f) : 0; mod->xxs[i].len = mod->xxs[i].lps + lsiz; mod->xxs[i].lpe = mod->xxs[i].lps + lsiz; mod->xxs[i].flg = lsiz > 1 ? XMP_SAMPLE_LOOP : 0; } mod->chn = 4; mod->pat = hio_read16b(f); mod->trk = mod->chn * mod->pat; mod->len = hio_read16b(f); hio_read(mod->xxo, 1, mod->len, f); mod->spd = hio_read16b(f); if (mod->spd > 10) { mod->bpm = 125 * mod->spd / 33; mod->spd = 6; } transp = hio_read8s(f); hio_read8(f); /* flags */ sliding = hio_read16b(f); /* sliding */ hio_read32b(f); /* jumping mask */ hio_seek(f, 16, SEEK_CUR); /* rgb */ /* read midi channels */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (mask & MASK) hio_read8(f); } /* read midi programs */ mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (mask & MASK) hio_read8(f); } MODULE_INFO(); D_(D_INFO "Sliding: %d", sliding); D_(D_INFO "Play transpose: %d", transp); if (sliding == 6) m->quirk |= QUIRK_VSALL | QUIRK_PBALL; for (i = 0; i < 32; i++) mod->xxi[i].sub[0].xpo = transp; if (pattern_init(mod) < 0) return -1; /* Load and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); for (i = 0; i < mod->pat; i++) { uint32 *conv; uint8 b, tracks; uint16 convsz; if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; tracks = hio_read8(f); b = hio_read8(f); convsz = hio_read16b(f); conv = calloc(1, convsz + 16); if (conv == NULL) return -1; if (b & M0F_LINEMSK00) *conv = 0L; else if (b & M0F_LINEMSK0F) *conv = 0xffffffff; else *conv = hio_read32b(f); if (b & M0F_LINEMSK10) *(conv + 1) = 0L; else if (b & M0F_LINEMSK1F) *(conv + 1) = 0xffffffff; else *(conv + 1) = hio_read32b(f); if (b & M0F_FXMSK00) *(conv + 2) = 0L; else if (b & M0F_FXMSK0F) *(conv + 2) = 0xffffffff; else *(conv + 2) = hio_read32b(f); if (b & M0F_FXMSK10) *(conv + 3) = 0L; else if (b & M0F_FXMSK1F) *(conv + 3) = 0xffffffff; else *(conv + 3) = hio_read32b(f); hio_read(conv + 4, 1, convsz, f); if (unpack_block(m, i, (uint8 *)conv) < 0) { free(conv); return -1; } free(conv); } /* Load samples */ D_(D_INFO "Instruments: %d", mod->ins); mask = hio_read32b(f); for (i = 0; i < 32; i++, mask <<= 1) { if (~mask & MASK) continue; mod->xxi[i].nsm = 1; mod->xxs[i].len = hio_read32b(f); if (mod->xxs[i].len == 0) mod->xxi[i].nsm = 0; if (hio_read16b(f)) /* type */ continue; 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, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol); if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; } return 0; }
static int mgt_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_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(); hio_read24b(f); /* MGT */ ver = hio_read8(f); hio_read32b(f); /* MCS */ set_type(m, "Megatracker MGT v%d.%d", MSN(ver), LSN(ver)); mod->chn = hio_read16b(f); hio_read16b(f); /* number of songs */ mod->len = hio_read16b(f); mod->pat = hio_read16b(f); mod->trk = hio_read16b(f); mod->ins = mod->smp = hio_read16b(f); hio_read16b(f); /* reserved */ hio_read32b(f); /* reserved */ sng_ptr = hio_read32b(f); seq_ptr = hio_read32b(f); ins_ptr = hio_read32b(f); pat_ptr = hio_read32b(f); trk_ptr = hio_read32b(f); smp_ptr = hio_read32b(f); hio_read32b(f); /* total smp len */ hio_read32b(f); /* unpacked trk size */ hio_seek(f, start + sng_ptr, SEEK_SET); hio_read(mod->name, 1, 32, f); seq_ptr = hio_read32b(f); mod->len = hio_read16b(f); mod->rst = hio_read16b(f); mod->bpm = hio_read8(f); mod->spd = hio_read8(f); hio_read16b(f); /* global volume */ hio_read8(f); /* master L */ hio_read8(f); /* master R */ for (i = 0; i < mod->chn; i++) { hio_read16b(f); /* pan */ } MODULE_INFO(); /* Sequence */ hio_seek(f, start + seq_ptr, SEEK_SET); for (i = 0; i < mod->len; i++) mod->xxo[i] = hio_read16b(f); /* Instruments */ if (instrument_init(mod) < 0) return -1; hio_seek(f, start + ins_ptr, SEEK_SET); for (i = 0; i < mod->ins; i++) { int c2spd, flags; if (subinstrument_alloc(mod, i , 1) < 0) return -1; hio_read(mod->xxi[i].name, 1, 32, f); sdata[i] = hio_read32b(f); mod->xxs[i].len = hio_read32b(f); mod->xxs[i].lps = hio_read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + hio_read32b(f); hio_read32b(f); hio_read32b(f); c2spd = hio_read32b(f); c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); mod->xxi[i].sub[0].vol = hio_read16b(f) >> 4; hio_read8(f); /* vol L */ hio_read8(f); /* vol R */ mod->xxi[i].sub[0].pan = 0x80; flags = hio_read8(f); mod->xxs[i].flg = flags & 0x03 ? XMP_SAMPLE_LOOP : 0; mod->xxs[i].flg |= flags & 0x02 ? XMP_SAMPLE_LOOP_BIDIR : 0; mod->xxi[i].sub[0].fin += 0 * hio_read8(f); // FIXME hio_read8(f); /* unused */ hio_read8(f); hio_read8(f); hio_read8(f); hio_read16b(f); hio_read32b(f); hio_read32b(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 %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_BIDIR ? 'B' : mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, c2spd); } /* PATTERN_INIT - alloc extra track*/ if (pattern_init(mod) < 0) return -1; D_(D_INFO "Stored tracks: %d", mod->trk); /* Tracks */ for (i = 1; i < mod->trk; i++) { int offset, rows; uint8 b; hio_seek(f, start + trk_ptr + i * 4, SEEK_SET); offset = hio_read32b(f); hio_seek(f, start + offset, SEEK_SET); rows = hio_read16b(f); if (track_alloc(mod, i, rows) < 0) return -1; //printf("\n=== Track %d ===\n\n", i); for (j = 0; j < rows; j++) { uint8 note, f2p; b = hio_read8(f); j += b & 0x03; note = 0; event = &mod->xxt[i]->event[j]; if (b & 0x04) note = hio_read8(f); if (b & 0x08) event->ins = hio_read8(f); if (b & 0x10) event->vol = hio_read8(f); if (b & 0x20) event->fxt = hio_read8(f); if (b & 0x40) event->fxp = hio_read8(f); if (b & 0x80) f2p = hio_read8(f); if (note == 1) event->note = XMP_KEY_OFF; else if (note > 11) /* adjusted to play codeine.mgt */ event->note = note + 1; /* 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);*/ } } /* Extra track */ mod->xxt[0] = calloc(sizeof(struct xmp_track) + sizeof(struct xmp_event) * 64 - 1, 1); mod->xxt[0]->rows = 64; /* Read and convert patterns */ D_(D_INFO "Stored patterns: %d", mod->pat); hio_seek(f, start + pat_ptr, SEEK_SET); for (i = 0; i < mod->pat; i++) { if (pattern_alloc(mod, i) < 0) return -1; mod->xxp[i]->rows = hio_read16b(f); for (j = 0; j < mod->chn; j++) { mod->xxp[i]->index[j] = hio_read16b(f) - 1; } } /* Read samples */ D_(D_INFO "Stored samples: %d", mod->smp); for (i = 0; i < mod->ins; i++) { if (mod->xxi[i].nsm == 0) continue; hio_seek(f, start + sdata[i], SEEK_SET); if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; } return 0; }
static int ptdt_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 mod_header mh; uint8 mod_event[4]; hio_read(&mh.name, 20, 1, f); for (i = 0; i < 31; i++) { hio_read(&mh.ins[i].name, 22, 1, f); mh.ins[i].size = hio_read16b(f); mh.ins[i].finetune = hio_read8(f); mh.ins[i].volume = hio_read8(f); mh.ins[i].loop_start = hio_read16b(f); mh.ins[i].loop_size = hio_read16b(f); } mh.len = hio_read8(f); mh.restart = hio_read8(f); hio_read(&mh.order, 128, 1, f); hio_read(&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; if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { if (subinstrument_alloc(mod, i, 1) < 0) return -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; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; 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].rls = 0xfff; instrument_name(mod, i, 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); } if (pattern_init(mod) < 0) return -1; /* Load 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 * 4); j++) { event = &EVENT(i, j % 4, j / 4); hio_read(mod_event, 1, 4, f); decode_protracker_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; if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0) return -1; } return 0; }
static int get_emic(struct module_data *m, int size, HIO_HANDLE * f, void *parm) { struct xmp_module *mod = &m->mod; int i, ver; uint8 reorder[256]; ver = hio_read16b(f); hio_read(mod->name, 1, 20, f); hio_seek(f, 20, SEEK_CUR); mod->bpm = hio_read8(f); mod->ins = hio_read8(f); mod->smp = mod->ins; m->quirk |= QUIRK_MODRNG; snprintf(mod->type, XMP_NAME_SIZE, "Quadra Composer EMOD v%d", ver); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; 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; if (subinstrument_alloc(mod, i, 1) < 0) return -1; sub = &xxi->sub[0]; hio_read8(f); /* num */ sub->vol = hio_read8(f); xxs->len = 2 * hio_read16b(f); hio_read(xxi->name, 1, 20, f); xxs->flg = hio_read8(f) & 1 ? XMP_SAMPLE_LOOP : 0; sub->fin = hio_read8s(f) << 4; xxs->lps = 2 * hio_read16b(f); xxs->lpe = xxs->lps + 2 * hio_read16b(f); hio_read32b(f); /* ptr */ xxi->nsm = 1; sub->pan = 0x80; sub->sid = i; D_(D_INFO "[%2X] %-20.20s %05x %05x %05x %c V%02x %+d", i, xxi->name, xxs->len, xxs->lps, xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ', sub->vol, sub->fin >> 4); } hio_read8(f); /* pad */ mod->pat = hio_read8(f); mod->trk = mod->pat * mod->chn; if (pattern_init(mod) < 0) return -1; memset(reorder, 0, 256); for (i = 0; i < mod->pat; i++) { reorder[hio_read8(f)] = i; if (pattern_tracks_alloc(mod, i, hio_read8(f) + 1) < 0) return -1; hio_seek(f, 20, SEEK_CUR); /* skip name */ hio_read32b(f); /* ptr */ } mod->len = hio_read8(f); D_(D_INFO "Module length: %d", mod->len); for (i = 0; i < mod->len; i++) mod->xxo[i] = reorder[hio_read8(f)]; return 0; }
static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; int i, j, k, x, y; struct xmp_event *event; struct stat st; char smp_filename[PATH_MAX]; HIO_HANDLE *s; int size1, size2; int pat_addr, pat_table[128][4]; uint8 buf[1024], mod_event[4]; int row; LOAD_INIT(); set_type(m, "Magnetic Fields Packer"); MODULE_INFO(); mod->chn = 4; mod->ins = mod->smp = 31; if (instrument_init(mod) < 0) return -1; for (i = 0; i < 31; i++) { int loop_size; if (subinstrument_alloc(mod, i, 1) < 0) return -1; mod->xxs[i].len = 2 * hio_read16b(f); mod->xxi[i].sub[0].fin = (int8)(hio_read8(f) << 4); mod->xxi[i].sub[0].vol = hio_read8(f); mod->xxs[i].lps = 2 * hio_read16b(f); loop_size = hio_read16b(f); mod->xxs[i].lpe = mod->xxs[i].lps + 2 * loop_size; mod->xxs[i].flg = loop_size > 1 ? XMP_SAMPLE_LOOP : 0; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxi[i].rls = 0xfff; if (mod->xxs[i].len > 0) mod->xxi[i].nsm = 1; D_(D_INFO "[%2X] %04x %04x %04x %c V%02x %+d", i, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe, loop_size > 1 ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4); } mod->len = mod->pat = hio_read8(f); hio_read8(f); /* restart */ for (i = 0; i < 128; i++) mod->xxo[i] = hio_read8(f); #if 0 for (i = 0; i < 128; i++) { mod->xxo[i] = hio_read8(f); if (mod->xxo[i] > mod->pat) mod->pat = mod->xxo[i]; } mod->pat++; #endif mod->trk = mod->pat * mod->chn; /* Read and convert patterns */ if (pattern_init(mod) < 0) return -1; size1 = hio_read16b(f); size2 = hio_read16b(f); for (i = 0; i < size1; i++) { /* Read pattern table */ for (j = 0; j < 4; j++) { pat_table[i][j] = hio_read16b(f); } } D_(D_INFO "Stored patterns: %d ", mod->pat); pat_addr = hio_tell(f); for (i = 0; i < mod->pat; i++) { if (pattern_tracks_alloc(mod, i, 64) < 0) return -1; for (j = 0; j < 4; j++) { hio_seek(f, pat_addr + pat_table[i][j], SEEK_SET); hio_read(buf, 1, 1024, f); for (row = k = 0; k < 4; k++) { for (x = 0; x < 4; x++) { for (y = 0; y < 4; y++, row++) { event = &EVENT(i, j, row); memcpy(mod_event, &buf[buf[buf[buf[k] + x] + y] * 2], 4); decode_protracker_event(event, mod_event); } } } } } /* Read samples */ D_(D_INFO "Loading samples: %d", mod->ins); /* first check smp.filename */ if (strlen(m->basename) < 5 || m->basename[3] != '.') { fprintf(stderr, "libxmp: invalid filename %s\n", m->basename); goto err; } m->basename[0] = 's'; m->basename[1] = 'm'; m->basename[2] = 'p'; snprintf(smp_filename, sizeof(smp_filename), "%s%s", m->dirname, m->basename); if (stat(smp_filename, &st) < 0) { /* handle .set filenames like in Kid Chaos*/ char *x; if (strchr(m->basename, '-')) { if ((x = strrchr(smp_filename, '-'))) strcpy(x, ".set"); } if (stat(smp_filename, &st) < 0) { fprintf(stderr, "libxmp: missing file %s\n", smp_filename); goto err; } } if ((s = hio_open_file(smp_filename, "rb")) == NULL) { fprintf(stderr, "libxmp: can't open sample file %s\n", smp_filename); goto err; } for (i = 0; i < mod->ins; i++) { if (load_sample(m, s, SAMPLE_FLAG_FULLREP, &mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0) return -1; } hio_close(s); m->quirk |= QUIRK_MODRNG; return 0; err: for (i = 0; i < mod->ins; i++) { mod->xxi[i].nsm = 0; memset(&mod->xxs[i], 0, sizeof(struct xmp_sample)); } return 0; }
static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i, c2spd; uint8 name[30]; mod->ins = mod->smp = hio_read16b(f); D_(D_INFO "Instruments : %d ", mod->ins); if (instrument_init(mod) < 0) return -1; for (i = 0; i < mod->ins; i++) { int fine, replen, flag; if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read32b(f); /* reserved */ mod->xxs[i].len = hio_read32b(f); mod->xxi[i].nsm = !!mod->xxs[i].len; fine = hio_read8s(f); /* finetune */ mod->xxi[i].sub[0].vol = hio_read8(f); mod->xxi[i].sub[0].pan = 0x80; mod->xxs[i].lps = hio_read32b(f); replen = hio_read32b(f); mod->xxs[i].lpe = mod->xxs[i].lps + replen - 1; mod->xxs[i].flg = replen > 2 ? XMP_SAMPLE_LOOP : 0; hio_read(name, 22, 1, f); instrument_name(mod, i, name, 22); flag = hio_read16b(f); /* bit 0-7:resol 8:stereo */ if ((flag & 0xff) > 8) { mod->xxs[i].flg |= XMP_SAMPLE_16BIT; mod->xxs[i].len >>= 1; mod->xxs[i].lps >>= 1; mod->xxs[i].lpe >>= 1; } hio_read32b(f); /* midi note (0x00300000) */ c2spd = hio_read32b(f); /* frequency */ c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin); /* It's strange that we have both c2spd and finetune */ mod->xxi[i].sub[0].fin += fine; mod->xxi[i].sub[0].sid = i; D_(D_INFO "[%2X] %-22.22s %05x%c%05x %05x %c%c %2db V%02x F%+03d %5d", i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ', mod->xxs[i].lps, replen, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', flag & 0x100 ? 'S' : ' ', flag & 0xff, mod->xxi[i].sub[0].vol, fine, c2spd); }