static int get_main(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; char buf[64]; int flags; hio_read(buf, 1, 64, f); strncpy(mod->name, buf, 63); /* ensure string terminator */ set_type(m, "Galaxy Music System 4.0"); flags = hio_read8(f); if (~flags & 0x01) m->quirk = QUIRK_LINEAR; mod->chn = hio_read8(f); mod->spd = hio_read8(f); mod->bpm = hio_read8(f); hio_read16l(f); /* unknown - 0x01c5 */ hio_read16l(f); /* unknown - 0xff00 */ hio_read8(f); /* unknown - 0x80 */ /* Sanity check */ if (mod->chn > 32) { return -1; } 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_ordr(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; mod->len = hio_read8(f); for (i = 0; i < mod->len; i++) mod->xxo[i] = hio_read8(f); return 0; }

static int get_ordr(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; mod->len = hio_read8(f) + 1; /* Don't follow Dr.Eggman's specs here */ for (i = 0; i < mod->len; i++) mod->xxo[i] = hio_read8(f); return 0; }

static int get_inst_cnt(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; hio_read32b(f); /* 42 01 00 00 */ hio_read8(f); /* 00 */ i = hio_read8(f) + 1; /* instrument number */ if (i > mod->ins) mod->ins = i; return 0; }

static int get_ordr(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; mod->len = hio_read8(f) + 1; if (hio_error(f)) { return -1; } for (i = 0; i < mod->len; i++) { mod->xxo[i] = hio_read8(f); } return 0; }

static inline uint32 read_bits(HIO_HANDLE *ibuf, uint32 *bitbuf, int *bitnum, int n) { uint32 retval = 0; int i = n; int bnum = *bitnum, bbuf = *bitbuf; if (n > 0) { do { if (bnum == 0) { bbuf = hio_read8(ibuf); bnum = 8; } retval >>= 1; retval |= bbuf << 31; bbuf >>= 1; bnum--; i--; } while (i != 0); i = n; *bitnum = bnum; *bitbuf = bbuf; } return (retval >> (32 - i)); }

static int get_inst_cnt(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; hio_read8(f); /* 00 */ i = hio_read8(f) + 1; /* instrument number */ if (i > mod->ins) mod->ins = i; hio_seek(f, 28, SEEK_CUR); /* skip name */ mod->smp += hio_read8(f); return 0; }

static int no_test(HIO_HANDLE *f, char *t, const int start) { if (hio_read32b(f) != 0x4e4f0000) /* NO 0x00 0x00 */ return -1; read_title(f, t, hio_read8(f)); return 0; }

static inline unsigned stream_read4(struct stream* s) { s->has_nibble = !s->has_nibble; if (!s->has_nibble) { return s->value & 0x0f; } else { s->value = hio_read8(s->f); return s->value >> 4; } }

static int get_patt(struct module_data *m, int size, HIO_HANDLE * f, void *parm) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j, k; uint8 x; D_(D_INFO "Stored patterns: %d", mod->pat); 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->ins = hio_read8(f); event->note = hio_read8(f) + 1; if (event->note != 0) event->note += 48; event->fxt = hio_read8(f) & 0x0f; event->fxp = hio_read8(f); /* Fix effects */ switch (event->fxt) { case 0x04: x = event->fxp; event->fxp = (x & 0xf0) | ((x << 1) & 0x0f); break; case 0x09: event->fxt <<= 1; break; case 0x0b: x = event->fxt; event->fxt = 16 * (x / 10) + x % 10; break; } } } } return 0; }

static int read_object_header(HIO_HANDLE *f, struct ObjectHeader *h, char *id) { hio_read(&h->id, 4, 1, f); D_(D_WARN "object id: %02x %02x %02x %02x", h->id[0], h->id[1], h->id[2], h->id[3]); if (memcmp(id, h->id, 4)) return -1; h->rc = hio_read8(f); if (h->rc != 0x20) return -1; if (hio_read(&h->name, 1, 32, f) != 32) return -1; h->eof = hio_read8(f); h->version = hio_read16l(f); h->headerSize = hio_read16l(f); D_(D_INFO "object %-4.4s (%d)", h->id, h->headerSize); return 0; }

static int get_patt_cnt(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; i = hio_read8(f) + 1; /* pattern number */ if (i > mod->pat) mod->pat = i; return 0; }

static int no_test(HIO_HANDLE *f, char *t, const int start) { int nsize, pat, chn; int i; hio_seek(f, start, SEEK_CUR); if (hio_read32b(f) != 0x4e4f0000) /* NO 0x00 0x00 */ return -1; nsize = hio_read8(f); if (nsize != 20) return -1; /* test title */ for (i = 0; i < nsize; i++) { if (hio_read8(f) == 0) return -1; } hio_seek(f, 9, SEEK_CUR); /* test number of patterns */ pat = hio_read8(f); if (pat == 0) return -1; hio_read8(f); /* test number of channels */ chn = hio_read8(f); if (chn <= 0 || chn > 16) return -1; hio_seek(f, start + 5, SEEK_SET); libxmp_read_title(f, t, nsize); 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, 110, SEEK_SET); if (hio_read8(f) > 64) return -1; if (hio_read8(f) > 128) return -1; hio_seek(f, 240, SEEK_SET); if (hio_read8(f) != 0xff) return -1; hio_seek(f, start + 2, SEEK_SET); read_title(f, t, 36); return 0; }

static int stm_test(HIO_HANDLE *f, char *t, const int start) { char buf[8]; hio_seek(f, start + 20, SEEK_SET); if (hio_read(buf, 1, 8, f) < 8) return -1; if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8)) return -1; hio_read8(f); if (hio_read8(f) != STM_TYPE_MODULE) return -1; if (hio_read8(f) < 1) /* We don't want STX files */ return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); return 0; }

static int get_init(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; char buf[64]; int flags; hio_read(buf, 1, 64, f); strncpy(mod->name, buf, 63); /* ensure string terminator */ libxmp_set_type(m, "Galaxy Music System 5.0"); flags = hio_read8(f); /* bit 0: Amiga period */ if (~flags & 0x01) m->period_type = PERIOD_LINEAR; mod->chn = hio_read8(f); mod->spd = hio_read8(f); mod->bpm = hio_read8(f); hio_read16l(f); /* unknown - 0x01c5 */ hio_read16l(f); /* unknown - 0xff00 */ hio_read8(f); /* unknown - 0x80 */ hio_read(data->chn_pan, 1, 64, f); return 0; }

static int s3m_test(HIO_HANDLE *f, char *t, const int start) { hio_seek(f, start + 44, SEEK_SET); if (hio_read32b(f) != MAGIC_SCRM) return -1; hio_seek(f, start + 29, SEEK_SET); if (hio_read8(f) != 0x10) return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 28); return 0; }

static void read_envelope(struct xmp_envelope *ei, struct it_envelope *env, HIO_HANDLE *f) { int j; env->flg = hio_read8(f); env->num = hio_read8(f); /* Sanity check */ if (env->num >= XMP_MAX_ENV_POINTS) { env->flg = 0; env->num = 0; return; } env->lpb = hio_read8(f); env->lpe = hio_read8(f); env->slb = hio_read8(f); env->sle = hio_read8(f); for (j = 0; j < 25; j++) { env->node[j].y = hio_read8(f); env->node[j].x = hio_read16l(f); } env->unused = hio_read8(f); ei->flg = env->flg & IT_ENV_ON ? XMP_ENVELOPE_ON : 0; ei->flg |= env->flg & IT_ENV_LOOP ? XMP_ENVELOPE_LOOP : 0; ei->flg |= env->flg & IT_ENV_SLOOP ? (XMP_ENVELOPE_SUS|XMP_ENVELOPE_SLOOP) : 0; ei->flg |= env->flg & IT_ENV_CARRY ? XMP_ENVELOPE_CARRY : 0; ei->npt = env->num; ei->sus = env->slb; ei->sue = env->sle; ei->lps = env->lpb; ei->lpe = env->lpe; if (ei->npt > 0 && ei->npt < XMP_MAX_ENV_POINTS) { for (j = 0; j < ei->npt; j++) { ei->data[j * 2] = env->node[j].x; ei->data[j * 2 + 1] = env->node[j].y; } } else { ei->flg &= ~XMP_ENVELOPE_ON; } }

static int rtm_test(HIO_HANDLE *f, char *t, const int start) { char buf[4]; if (hio_read(buf, 1, 4, f) < 4) return -1; if (memcmp(buf, "RTMM", 4)) return -1; if (hio_read8(f) != 0x20) return -1; libxmp_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 mgt_test(HIO_HANDLE *f, char *t, const int start) { int sng_ptr; if (hio_read24b(f) != MAGIC_MGT) return -1; hio_read8(f); if (hio_read32b(f) != MAGIC_MCS) return -1; hio_seek(f, 18, SEEK_CUR); sng_ptr = hio_read32b(f); hio_seek(f, start + sng_ptr, SEEK_SET); read_title(f, t, 32); 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 amf_test(HIO_HANDLE * f, char *t, const int start) { char buf[4]; int ver; if (hio_read(buf, 1, 3, f) < 3) return -1; if (buf[0] != 'A' || buf[1] != 'M' || buf[2] != 'F') return -1; ver = hio_read8(f); if (ver < 0x0a || ver > 0x0e) return -1; read_title(f, t, 32); return 0; }

static int stc_test(HIO_HANDLE * f, char *t, const int start) { int pos_ptr, orn_ptr, pat_ptr; int i, len, max_pat; hio_seek(f, start, SEEK_SET); if (hio_read8(f) > 0x20) /* Check tempo */ return -1; pos_ptr = hio_read16l(f); /* Positions pointer */ orn_ptr = hio_read16l(f); /* Ornaments pointer */ pat_ptr = hio_read16l(f); /* Patterns pointer */ if (pos_ptr < 138 || orn_ptr < 138 || pat_ptr < 138) return -1; hio_seek(f, start + pos_ptr, SEEK_SET); len = hio_read8(f) + 1; for (max_pat = i = 0; i < len; i++) { int pat = hio_read8(f); if (pat > MAX_PAT) /* Check orders */ return -1; if (pat > max_pat) max_pat = pat; hio_read8(f); } hio_seek(f, pat_ptr, SEEK_SET); for (i = 0; i < max_pat; i++) { int num = hio_read8(f); /* Check track pointers */ if (num != (i + 1)) return -1; hio_read16l(f); hio_read16l(f); hio_read16l(f); } if (hio_read8(f) != 0xff) return -1; hio_seek(f, start + 7, SEEK_SET); read_title(f, t, 18); 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 depack_hrt(HIO_HANDLE *in, FILE *out) { uint8 buf[1024]; uint8 c1, c2, c3, c4; int len, npat; int ssize = 0; int i, j; memset(buf, 0, 950); hio_read(buf, 950, 1, in); /* read header */ for (i = 0; i < 31; i++) /* erase addresses */ *(uint32 *)(buf + 38 + 30 * i) = 0; fwrite(buf, 950, 1, out); /* write header */ for (i = 0; i < 31; i++) /* samples size */ ssize += readmem16b(buf + 42 + 30 * i) * 2; write8(out, len = hio_read8(in)); /* song length */ write8(out, hio_read8(in)); /* nst byte */ hio_read(buf, 1, 128, in); /* pattern list */ npat = 0; /* number of patterns */ for (i = 0; i < 128; i++) { if (buf[i] > npat) npat = buf[i]; } npat++; write32b(out, PW_MOD_MAGIC); /* write ptk ID */ /* pattern data */ hio_seek(in, 1084, SEEK_SET); for (i = 0; i < npat; i++) { for (j = 0; j < 256; j++) { buf[0] = hio_read8(in); buf[1] = hio_read8(in); buf[2] = hio_read8(in); buf[3] = hio_read8(in); buf[0] /= 2; c1 = buf[0] & 0xf0; if (buf[1] == 0) c2 = 0; else { c1 |= ptk_table[buf[1] / 2][0]; c2 = ptk_table[buf[1] / 2][1]; } c3 = ((buf[0] << 4) & 0xf0) | buf[2]; c4 = buf[3]; write8(out, c1); write8(out, c2); write8(out, c3); write8(out, c4); } } /* sample data */ pw_move_data(out, in, ssize); 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 asylum_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct xmp_module *mod = &m->mod; struct xmp_event *event; int i, j; LOAD_INIT(); hio_seek(f, 32, SEEK_CUR); /* skip magic */ mod->spd = hio_read8(f); /* initial speed */ mod->bpm = hio_read8(f); /* initial BPM */ mod->ins = hio_read8(f); /* number of instruments */ mod->pat = hio_read8(f); /* number of patterns */ mod->len = hio_read8(f); /* module length */ hio_read8(f); hio_read(mod->xxo, 1, mod->len, f); /* read orders */ hio_seek(f, start + 294, SEEK_SET); mod->chn = 8; mod->smp = mod->ins; mod->trk = mod->pat * mod->chn; snprintf(mod->type, XMP_NAME_SIZE, "Asylum Music Format v1.0"); MODULE_INFO(); if (instrument_init(mod) < 0) return -1; /* Read and convert instruments and samples */ for (i = 0; i < mod->ins; i++) { uint8 insbuf[37]; if (subinstrument_alloc(mod, i, 1) < 0) return -1; hio_read(insbuf, 1, 37, f); instrument_name(mod, i, insbuf, 22); mod->xxi[i].sub[0].fin = (int8)(insbuf[22] << 4); mod->xxi[i].sub[0].vol = insbuf[23]; mod->xxi[i].sub[0].xpo = (int8)insbuf[24]; mod->xxi[i].sub[0].pan = 0x80; mod->xxi[i].sub[0].sid = i; mod->xxs[i].len = readmem32l(insbuf + 25); mod->xxs[i].lps = readmem32l(insbuf + 29); mod->xxs[i].lpe = mod->xxs[i].lps + readmem32l(insbuf + 33); mod->xxs[i].flg = mod->xxs[i].lpe > 2 ? XMP_SAMPLE_LOOP : 0; 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, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin); } hio_seek(f, 37 * (64 - mod->ins), SEEK_CUR); 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++) { uint8 note; event = &EVENT(i, j % mod->chn, j / mod->chn); memset(event, 0, sizeof(struct xmp_event)); note = hio_read8(f); if (note != 0) { event->note = note + 13; } event->ins = hio_read8(f); event->fxt = hio_read8(f); event->fxp = hio_read8(f); } } /* 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; mod->xxi[i].nsm = 1; } } 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; }