int pw_test_format(HIO_HANDLE *f, char *t, const int start, struct xmp_test_info *info) { unsigned char *b; int extra; int s = BUF_SIZE; b = calloc(1, BUF_SIZE); if (b == NULL) return -1; s = hio_read(b, 1, s, f); while ((extra = pw_check(b, s, info)) > 0) { unsigned char *buf = realloc(b, s + extra); if (buf == NULL) { free(b); return -1; } b = buf; if (hio_read(b + s, extra, 1, f) == 0) { free(b); return -1; } s += extra; } free(b); return extra == 0 ? 0 : -1; }
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_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; }
static int mod_test(HIO_HANDLE *f, char *t, const int start) { int i; char buf[4]; hio_seek(f, start + 1080, SEEK_SET); if (hio_read(buf, 1, 4, f) < 4) return -1; if (!strncmp(buf + 2, "CH", 2) && isdigit((int)buf[0]) && isdigit((int)buf[1])) { i = (buf[0] - '0') * 10 + buf[1] - '0'; if (i > 0 && i <= 32) { goto found; } } if (!strncmp(buf + 1, "CHN", 3) && isdigit((int)*buf)) { if (*buf >= '0' && *buf <='9') { goto found; } } if (memcmp(buf, "M.K.", 4)) return -1; found: hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); return 0; }
static int mmd3_test(HIO_HANDLE *f, char *t, const int start) { char id[4]; uint32 offset, len; if (hio_read(id, 1, 4, f) < 4) return -1; if (memcmp(id, "MMD2", 4) && memcmp(id, "MMD3", 4)) return -1; hio_seek(f, 28, SEEK_CUR); offset = hio_read32b(f); /* expdata_offset */ if (offset) { hio_seek(f, start + offset + 44, SEEK_SET); offset = hio_read32b(f); len = hio_read32b(f); hio_seek(f, start + offset, SEEK_SET); read_title(f, t, len); } else { read_title(f, t, 0); } return 0; }
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; }
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); 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 get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; hio_read(mod->xxo, 1, mod->len, f); return 0; }
static int stx_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_seek(f, start + 60, SEEK_SET); if (hio_read(buf, 1, 4, f) < 4) return -1; if (memcmp(buf, "SCRM", 4)) return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); 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 mfp_test(HIO_HANDLE *f, char *t, const int start) { uint8 buf[384]; int i, len, lps, lsz; if (HIO_HANDLE_TYPE(f) != HIO_HANDLE_TYPE_FILE) return -1; if (hio_read(buf, 1, 384, f) < 384) return -1; /* check restart byte */ if (buf[249] != 0x7f) return -1; for (i = 0; i < 31; i++) { /* check size */ len = readmem16b(buf + i * 8); if (len > 0x7fff) return -1; /* check finetune */ if (buf[i * 8 + 2] & 0xf0) return -1; /* check volume */ if (buf[i * 8 + 3] > 0x40) return -1; /* check loop start */ lps = readmem16b(buf + i * 8 + 4); if (lps > len) return -1; /* check loop size */ lsz = readmem16b(buf + i * 8 + 6); if (lps + lsz - 1 > len) return -1; if (len > 0 && lsz == 0) return -1; } if (buf[248] != readmem16b(buf + 378)) return -1; if (readmem16b(buf + 378) != readmem16b(buf + 380)) return -1; read_title(f, t, 0); return 0; }
int pw_wizardry(HIO_HANDLE *file_in, FILE *file_out, char **name) { int in_size; uint8 *data; char title[21]; int i; in_size = hio_size(file_in); /* printf ("input file size : %d\n", in_size); */ if (in_size < MIN_FILE_LENGHT) return -2; /* alloc mem */ data = (uint8 *)malloc (in_size + 4096); /* slack added */ if (data == NULL) { /*perror("Couldn't allocate memory");*/ return -1; } hio_read(data, in_size, 1, file_in); /********************************************************************/ /************************** SEARCH ******************************/ /********************************************************************/ for (i = 0; pw_format[i] != NULL; i++) { D_("checking format: %s", pw_format[i]->name); if (pw_format[i]->test(data, title, in_size) >= 0) break; } if (pw_format[i] == NULL) { free(data); return -1; } hio_seek(file_in, 0, SEEK_SET); if (pw_format[i]->depack(file_in, file_out) < 0) { free(data); return -1; } fflush(file_out); free(data); if (name != NULL) { *name = pw_format[i]->name; } return 0; }
static int tcb_test(HIO_HANDLE *f, char *t, const int start) { uint8 buffer[10]; if (hio_read(buffer, 1, 8, f) < 8) return -1; if (memcmp(buffer, "AN COOL.", 8) && memcmp(buffer, "AN COOL!", 8)) return -1; libxmp_read_title(f, t, 0); return 0; }
int pw_move_data(FILE *out, HIO_HANDLE *in, int len) { uint8 buf[1024]; int l; do { l = hio_read(buf, 1, len > 1024 ? 1024 : len, in); fwrite(buf, 1, l, out); len -= l; } while (l > 0 && len > 0); return 0; }
static int gtk_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, "GTK", 3) || buf[3] > 4) return -1; read_title(f, t, 32); 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 xm_test(HIO_HANDLE *f, char *t, const int start) { char buf[20]; if (hio_read(buf, 1, 17, f) < 17) /* ID text */ return -1; if (memcmp(buf, "Extended Module: ", 17)) return -1; read_title(f, t, 20); return 0; }
static int asylum_test(HIO_HANDLE *f, char *t, const int start) { char buf[32]; if (hio_read(buf, 1, 32, f) < 32) return -1; if (memcmp(buf, "ASYLUM Music Format V1.0\0\0\0\0\0\0\0\0", 32)) return -1; read_title(f, t, 0); 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 okt_test(HIO_HANDLE *f, char *t, const int start) { char magic[8]; if (hio_read(magic, 1, 8, f) < 8) return -1; if (strncmp(magic, "OKTASONG", 8)) return -1; read_title(f, t, 0); return 0; }
static int rad_test(HIO_HANDLE *f, char *t, const int start) { char buf[16]; if (hio_read(buf, 1, 16, f) < 16) return -1; if (memcmp(buf, "RAD by REALiTY!!", 16)) return -1; read_title(f, t, 0); return 0; }
static int mtp_test(HIO_HANDLE *f, char *t, const int start) { char buf[6]; if (hio_read(buf, 1, 6, f) < 6) return -1; if (memcmp(buf, "SONGOK", 6) && memcmp(buf, "IAN92a", 6)) return -1; read_title(f, t, 0); return 0; }
static int hsc_test(HIO_HANDLE *f, char *t, const int start) { int p, i, r, c; uint8 buf[1200]; hio_seek(f, 128 * 12, SEEK_CUR); if (hio_read(buf, 1, 51, f) != 51) return -1; for (p = i = 0; i < 51; i++) { if (buf[i] == 0xff) break; if (buf[i] > p) p = buf[i]; } if (!i || !p || i > 50 || p > 50) /* Test number of patterns */ return -1; for (i = 0; i < p; i++) { hio_read(buf, 1, 64 * 9 * 2, f); for (r = 0; r < 64; r++) { for (c = 0; c < 9; c++) { uint8 n = buf[r * 9 * 2 + c * 2]; uint8 m = buf[r * 9 * 2 + c * 2 + 1]; if (m > 0x06 && m < 0x10 && n != 0x80) /* Test effects 07..0f */ return -1; if (MSN(m) > 6 && MSN(m) < 10) /* Test effects 7x .. 9x */ return -1; } } } libxmp_read_title(f, t, 0); return 0; }
static int mtm_test(HIO_HANDLE *f, char *t, const int start) { uint8 buf[4]; if (hio_read(buf, 1, 4, f) < 4) return -1; if (memcmp(buf, "MTM", 3)) return -1; if (buf[3] != 0x10) return -1; read_title(f, t, 20); return 0; }
static int amd_test(HIO_HANDLE *f, char *t, const int start) { char buf[9]; hio_seek(f, start + 1062, SEEK_SET); if (hio_read(buf, 1, 9, f) < 9) return -1; if (memcmp(buf, "<o", 2) || memcmp(buf + 6, "RoR", 3)) return -1; hio_seek(f, start + 0, SEEK_SET); libxmp_read_title(f, t, 24); return 0; }
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; }
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 int pt3_load(struct module_data *m, HIO_HANDLE *f, const int start) { iff_handle handle; char buf[20]; int ret; LOAD_INIT(); hio_read32b(f); /* FORM */ hio_read32b(f); /* size */ hio_read32b(f); /* MODL */ hio_read32b(f); /* VERS */ hio_read32b(f); /* VERS size */ hio_read(buf, 1, 10, f); set_type(m, "%-6.6s IFFMODL", buf + 4); handle = iff_new(); if (handle == NULL) return -1; /* IFF chunk IDs */ ret = iff_register(handle, "INFO", get_info); ret |= iff_register(handle, "CMNT", get_cmnt); ret |= iff_register(handle, "PTDT", get_ptdt); if (ret != 0) return -1; iff_set_quirk(handle, IFF_FULL_CHUNK_SIZE); /* Load IFF chunks */ if (iff_load(handle, m, f, NULL) < 0) { iff_release(handle); return -1; } iff_release(handle); /* Sanity check */ if (m->mod.smp <= 0) { return -1; } return 0; }
static int alm_test(HIO_HANDLE *f, char *t, const int start) { char buf[7]; if (HIO_HANDLE_TYPE(f) != HIO_HANDLE_TYPE_FILE) return -1; if (hio_read(buf, 1, 7, f) < 7) return -1; if (memcmp(buf, "ALEYMOD", 7) && memcmp(buf, "ALEY MO", 7)) return -1; read_title(f, t, 0); return 0; }
static int ult_test(HIO_HANDLE *f, char *t, const int start) { char buf[15]; if (hio_read(buf, 1, 15, f) < 15) return -1; if (memcmp(buf, "MAS_UTrack_V000", 14)) return -1; if (buf[14] < '0' || buf[14] > '4') return -1; read_title(f, t, 32); return 0; }