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);
}
Exemple #2
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);
}
Exemple #3
0
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");
}
Exemple #4
0
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);
	}
}
Exemple #5
0
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;
}
Exemple #6
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);
    }
Exemple #7
0
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);
	}
Exemple #8
0
static int gdm_load(struct xmp_context *ctx, FILE *f, const int start)
{
	struct xmp_player_context *p = &ctx->p;
	struct xmp_mod_context *m = &p->m;
	struct xxm_event *event;
	int vermaj, vermin, tvmaj, tvmin, tracker;
	int origfmt, ord_ofs, pat_ofs, ins_ofs, smp_ofs;
	uint8 buffer[32], panmap[32];
	int i;

	LOAD_INIT();

	read32b(f);		/* skip magic */
	fread(m->name, 1, 32, f);
	fread(m->author, 1, 32, f);

	fseek(f, 7, SEEK_CUR);

	vermaj = read8(f);
	vermin = read8(f);
	tracker = read16l(f);
	tvmaj = read8(f);
	tvmin = read8(f);

	if (tracker == 0) {
		sprintf(m->type, "GDM %d.%02d, (2GDM %d.%02d)",
					vermaj, vermin, tvmaj, tvmin);
	} else {
		sprintf(m->type, "GDM %d.%02d (unknown tracker %d.%02d)",
					vermaj, vermin, tvmaj, tvmin);
	}

	fread(panmap, 32, 1, f);
	for (i = 0; i < 32; i++) {
		if (panmap[i] != 0xff)
			m->xxh->chn = i + 1;
		if (panmap[i] == 16)
			panmap[i] = 8;
		m->xxc[i].pan = 0x80 + (panmap[i] - 8) * 16;
	}

	m->xxh->gvl = read8(f);
	m->xxh->tpo = read8(f);
	m->xxh->bpm = read8(f);
	origfmt = read16l(f);
	ord_ofs = read32l(f);
	m->xxh->len = read8(f);
	pat_ofs = read32l(f);
	m->xxh->pat = read8(f);
	ins_ofs = read32l(f);
	smp_ofs = read32l(f);
	m->xxh->ins = m->xxh->smp = read8(f);
	m->xxh->trk = m->xxh->pat * m->xxh->chn;
	
	MODULE_INFO();

	if (origfmt > 9)
		origfmt = 9;
	reportv(ctx, 0, "Orig format    : %s\n", fmt[origfmt]);

	fseek(f, start + ord_ofs, SEEK_SET);

	for (i = 0; i < m->xxh->len; i++)
		m->xxo[i] = read8(f);

	/* Read instrument data */

	fseek(f, start + ins_ofs, SEEK_SET);

	INSTRUMENT_INIT();

	reportv(ctx, 1, "     Name                             Len   LBeg  LEnd  L Vol Pan C4Spd\n");

	for (i = 0; i < m->xxh->ins; i++) {
		int flg, c4spd, vol, pan;

		m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1);
		fread(buffer, 32, 1, f);
		copy_adjust(m->xxih[i].name, buffer, 32);
		fseek(f, 12, SEEK_CUR);		/* skip filename */
		read8(f);			/* skip EMS handle */
		m->xxs[i].len = read32l(f);
		m->xxs[i].lps = read32l(f);
		m->xxs[i].lpe = read32l(f);
		flg = read8(f);
		c4spd = read16l(f);
		vol = read8(f);
		pan = read8(f);
		
		m->xxi[i][0].vol = vol > 0x40 ? 0x40 : vol;
		m->xxi[i][0].pan = pan > 15 ? 0x80 : 0x80 + (pan - 8) * 16;
		c2spd_to_note(c4spd, &m->xxi[i][0].xpo, &m->xxi[i][0].fin);

		m->xxih[i].nsm = !!(m->xxs[i].len);
		m->xxi[i][0].sid = i;
		m->xxs[i].flg = 0;

		if (flg & 0x01)
			m->xxs[i].flg |= WAVE_LOOPING;
		if (flg & 0x02)
			m->xxs[i].flg |= WAVE_16_BITS;

		if (V(1) && (strlen((char*)m->xxih[i].name) || (m->xxs[i].len > 1))) {
			report("[%2X] %-32.32s %05x%c%05x %05x %c V%02x P%02x %5d\n",
				i, m->xxih[i].name,
				m->xxs[i].len,
				m->xxs[i].flg & WAVE_16_BITS ? '+' : ' ',
				m->xxs[i].lps,
				m->xxs[i].lpe,
				m->xxs[i].flg & WAVE_LOOPING ? 'L' : ' ',
				m->xxi[i][0].vol,
				m->xxi[i][0].pan,
				c4spd);
		}


	}

	/* Read and convert patterns */

	fseek(f, start + pat_ofs, SEEK_SET);

	PATTERN_INIT();

	reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat);

	for (i = 0; i < m->xxh->pat; i++) {
		int len, c, r, k;

		PATTERN_ALLOC(i);
		m->xxp[i]->rows = 64;
		TRACK_ALLOC(i);

		len = read16l(f);
		len -= 2;

		for (r = 0; len > 0; ) {
			c = read8(f);
			len--;

			if (c == 0) {
				r++;
				continue;
			}

			assert((c & 0x1f) < m->xxh->chn);
			event = &EVENT (i, c & 0x1f, r);

			if (c & 0x20) {		/* note and sample follows */
				k = read8(f);
				event->note = 12 * MSN(k & 0x7f) + LSN(k);
				event->ins = read8(f);
				len -= 2;
			}

			if (c & 0x40) {		/* effect(s) follow */
				do {
					k = read8(f);
					len--;
					switch ((k & 0xc0) >> 6) {
					case 0:
						event->fxt = k & 0x1f;
						event->fxp = read8(f);
						len--;
						fix_effect(&event->fxt, &event->fxp);
						break;
					case 1:
						event->f2t = k & 0x1f;
						event->f2p = read8(f);
						len--;
						fix_effect(&event->f2t, &event->f2p);
						break;
					case 2:
						read8(f);
						len--;
					}
				} while (k & 0x20);
			}
		}
		
		reportv(ctx, 0, ".");
	}
	reportv(ctx, 0, "\n");

	/* Read samples */

	fseek(f, start + smp_ofs, SEEK_SET);

	reportv(ctx, 0, "Stored samples : %d ", m->xxh->smp);
	for (i = 0; i < m->xxh->ins; i++) {
		xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate,
				XMP_SMP_UNS, &m->xxs[m->xxi[i][0].sid], NULL);
		reportv(ctx, 0, ".");
	}
	reportv(ctx, 0, "\n");

	return 0;
}
Exemple #9
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);
	}
Exemple #10
0
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;
}
Exemple #11
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;
}
Exemple #12
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);
	}
    }
Exemple #14
0
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);
    }
Exemple #15
0
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;
				}
			}
		}
Exemple #17
0
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);
}
Exemple #18
0
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;
}
Exemple #20
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;
}
Exemple #21
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);
    }
Exemple #22
0
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;
}
Exemple #23
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;
				}
			}
		}