Ejemplo n.º 1
0
static void get_smpl(struct xmp_context *ctx, int size, FILE *f)
{
	struct xmp_player_context *p = &ctx->p;
	struct xmp_mod_context *m = &p->m;
	int i, flags;

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

	reportv(ctx, 2, "\n     Flags    Len   LBeg  LEnd  L");

	for (i = 0; i < m->xxh->smp; i++) {
		flags = read32b(f);
		m->xxs[i].len = read32b(f);

		if (flags & 0x02) {
			m->xxs[i].flg |= WAVE_16_BITS;
			m->xxs[i].len <<= 1;
			m->xxs[i].lps <<= 1;
			m->xxs[i].lpe <<= 1;
		}

		if (flags & 0x04) {	/* Skip 32-bit samples */
			m->xxs[i].len <<= 2;
			fseek(f, m->xxs[i].len, SEEK_CUR);
			continue;
		}
		
		xmp_drv_loadpatch(ctx, f, i, m->c4rate, XMP_SMP_BIGEND,
							&m->xxs[i], NULL);

		if (m->xxs[i].len == 0)
			continue;

		reportv(ctx, 2, "\n[%2X] %08x %05x%c%05x %05x %c ",
			i, flags, 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 ?
			(m->xxs[i].flg & WAVE_BIDIR_LOOP ? 'B' : 'L') : ' ');

		reportv(ctx, 0, ".");
	}
	reportv(ctx, 0, "\n");
}
static void get_sbod(struct xmp_context *ctx, int size, FILE *f)
{
    struct xmp_player_context *p = &ctx->p;
    struct xmp_mod_context *m = &p->m;

    int flags = 0;
    int i;

    if (sample >= m->xxh->ins)
	return;

    if (!sample && V(0))
	report ("\nStored samples : %d ", m->xxh->smp);

    i = idx[sample];
    if (mode[i] == OKT_MODE8 || mode[i] == OKT_MODEB)
	flags = XMP_SMP_7BIT;

    xmp_drv_loadpatch(ctx, f, sample, m->c4rate, flags, &m->xxs[i], NULL);

    reportv(ctx, 0, ".");

    sample++;
}
Ejemplo n.º 3
0
static int ptm_load(struct xmp_context *ctx, FILE *f, const int start)
{
    struct xmp_player_context *p = &ctx->p;
    struct xmp_mod_context *m = &p->m;
    int c, r, i, smp_ofs[256];
    struct xxm_event *event;
    struct ptm_file_header pfh;
    struct ptm_instrument_header pih;
    uint8 n, b;

    LOAD_INIT();

    /* Load and convert header */

    fread(&pfh.name, 28, 1, f);		/* Song name */
    pfh.doseof = read8(f);		/* 0x1a */
    pfh.vermin = read8(f);		/* Minor version */
    pfh.vermaj = read8(f);		/* Major type */
    pfh.rsvd1 = read8(f);		/* Reserved */
    pfh.ordnum = read16l(f);		/* Number of orders (must be even) */
    pfh.insnum = read16l(f);		/* Number of instruments */
    pfh.patnum = read16l(f);		/* Number of patterns */
    pfh.chnnum = read16l(f);		/* Number of channels */
    pfh.flags = read16l(f);		/* Flags (set to 0) */
    pfh.rsvd2 = read16l(f);		/* Reserved */
    pfh.magic = read32b(f); 		/* 'PTMF' */

#if 0
    if (pfh.magic != MAGIC_PTMF)
	return -1;
#endif

    fread(&pfh.rsvd3, 16, 1, f);	/* Reserved */
    fread(&pfh.chset, 32, 1, f);	/* Channel settings */
    fread(&pfh.order, 256, 1, f);	/* Orders */
    for (i = 0; i < 128; i++)
	pfh.patseg[i] = read16l(f);

    m->xxh->len = pfh.ordnum;
    m->xxh->ins = pfh.insnum;
    m->xxh->pat = pfh.patnum;
    m->xxh->chn = pfh.chnnum;
    m->xxh->trk = m->xxh->pat * m->xxh->chn;
    m->xxh->smp = m->xxh->ins;
    m->xxh->tpo = 6;
    m->xxh->bpm = 125;
    memcpy (m->xxo, pfh.order, 256);

    m->c4rate = C4_NTSC_RATE;

    copy_adjust((uint8 *)m->name, pfh.name, 28);
    sprintf(m->type, "PTMF %d.%02x (Poly Tracker)",
	pfh.vermaj, pfh.vermin);

    MODULE_INFO();

    INSTRUMENT_INIT();

    /* Read and convert instruments and samples */

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

    for (i = 0; i < m->xxh->ins; i++) {
	m->xxi[i] = calloc (sizeof (struct xxm_instrument), 1);

	pih.type = read8(f);			/* Sample type */
	fread(&pih.dosname, 12, 1, f);		/* DOS file name */
	pih.vol = read8(f);			/* Volume */
	pih.c4spd = read16l(f);			/* C4 speed */
	pih.smpseg = read16l(f);		/* Sample segment (not used) */
	pih.smpofs = read32l(f);		/* Sample offset */
	pih.length = read32l(f);		/* Length */
	pih.loopbeg = read32l(f);		/* Loop begin */
	pih.loopend = read32l(f);		/* Loop end */
	pih.gusbeg = read32l(f);		/* GUS begin address */
	pih.guslps = read32l(f);		/* GUS loop start address */
	pih.guslpe = read32l(f);		/* GUS loop end address */
	pih.gusflg = read8(f);			/* GUS loop flags */
	pih.rsvd1 = read8(f);			/* Reserved */
	fread(&pih.name, 28, 1, f);		/* Instrument name */
	pih.magic = read32b(f);			/* 'PTMS' */

	if ((pih.type & 3) != 1)
	    continue;

	smp_ofs[i] = pih.smpofs;
	m->xxih[i].nsm = !!(m->xxs[i].len = pih.length);
	m->xxs[i].lps = pih.loopbeg;
	m->xxs[i].lpe = pih.loopend;
	if (m->xxs[i].lpe)
		m->xxs[i].lpe--;
	m->xxs[i].flg = pih.type & 0x04 ? WAVE_LOOPING : 0;
	m->xxs[i].flg |= pih.type & 0x08 ? WAVE_LOOPING | WAVE_BIDIR_LOOP : 0;
	m->xxs[i].flg |= pih.type & 0x10 ? WAVE_16_BITS : 0;
	m->xxi[i][0].vol = pih.vol;
	m->xxi[i][0].pan = 0x80;
	m->xxi[i][0].sid = i;
	pih.magic = 0;

	copy_adjust(m->xxih[i].name, pih.name, 28);

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

	/* Convert C4SPD to relnote/finetune */
	c2spd_to_note (pih.c4spd, &m->xxi[i][0].xpo, &m->xxi[i][0].fin);
    }

    PATTERN_INIT();

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

    for (i = 0; i < m->xxh->pat; i++) {
	if (!pfh.patseg[i])
	    continue;
	PATTERN_ALLOC (i);
	m->xxp[i]->rows = 64;
	TRACK_ALLOC (i);
	fseek(f, start + 16L * pfh.patseg[i], SEEK_SET);
	r = 0;
	while (r < 64) {
	    fread (&b, 1, 1, f);
	    if (!b) {
		r++;
		continue;
	    }

	    c = b & PTM_CH_MASK;
	    if (c >= m->xxh->chn)
		continue;

	    event = &EVENT (i, c, r);
	    if (b & PTM_NI_FOLLOW) {
		fread (&n, 1, 1, f);
		switch (n) {
		case 255:
		    n = 0;
		    break;	/* Empty note */
		case 254:
		    n = XMP_KEY_OFF;
		    break;	/* Key off */
		}
		event->note = n;
		fread (&n, 1, 1, f);
		event->ins = n;
	    }
	    if (b & PTM_FX_FOLLOWS) {
		event->fxt = read8(f);
		event->fxp = read8(f);

		if (event->fxt > 0x17)
			event->fxt = event->fxp = 0;

		switch (event->fxt) {
		case 0x0e:	/* Extended effect */
		    if (MSN(event->fxp) == 0x8) {	/* Pan set */
			event->fxt = FX_SETPAN;
			event->fxp = LSN (event->fxp) << 4;
		    }
		    break;
		case 0x10:	/* Set global volume */
		    event->fxt = FX_GLOBALVOL;
		    break;
		case 0x11:	/* Multi retrig */
		    event->fxt = FX_MULTI_RETRIG;
		    break;
		case 0x12:	/* Fine vibrato */
		    event->fxt = FX_FINE4_VIBRA;
		    break;
		case 0x13:	/* Note slide down */
		    event->fxt = FX_NSLIDE_DN;
		    break;
		case 0x14:	/* Note slide up */
		    event->fxt = FX_NSLIDE_UP;
		    break;
		case 0x15:	/* Note slide down + retrig */
		    event->fxt = FX_NSLIDE_R_DN;
		    break;
		case 0x16:	/* Note slide up + retrig */
		    event->fxt = FX_NSLIDE_R_UP;
		    break;
		case 0x17:	/* Reverse sample */
		    event->fxt = event->fxp = 0;
		    break;
		}
	    }
	    if (b & PTM_VOL_FOLLOWS) {
		event->vol = read8(f) + 1;
	    }
	}
	reportv(ctx, 0, ".");
    }

    reportv(ctx, 0, "\nStored samples : %d ", m->xxh->smp);

    for (i = 0; i < m->xxh->smp; i++) {
	if (!m->xxs[i].len)
	    continue;
	fseek(f, start + smp_ofs[m->xxi[i][0].sid], SEEK_SET);
	xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate,
			XMP_SMP_8BDIFF, &m->xxs[m->xxi[i][0].sid], NULL);
	reportv(ctx, 0, ".");
    }
    reportv(ctx, 0, "\n");

    m->vol_xlat = ptm_vol;

    for (i = 0; i < m->xxh->chn; i++)
	m->xxc[i].pan = pfh.chset[i] << 4;

    return 0;
}
static int mgt_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;
	int ver;
	int sng_ptr, seq_ptr, ins_ptr, pat_ptr, trk_ptr, smp_ptr;
	int sdata[64];

	LOAD_INIT();

	read24b(f);		/* MGT */
	ver = read8(f);
	read32b(f);		/* MCS */

	sprintf(m->type, "MGT v%d.%d (Megatracker)", MSN(ver), LSN(ver));

	m->xxh->chn = read16b(f);
	read16b(f);			/* number of songs */
	m->xxh->len = read16b(f);
	m->xxh->pat = read16b(f);
	m->xxh->trk = read16b(f);
	m->xxh->ins = m->xxh->smp = read16b(f);
	read16b(f);			/* reserved */
	read32b(f);			/* reserved */

	sng_ptr = read32b(f);
	seq_ptr = read32b(f);
	ins_ptr = read32b(f);
	pat_ptr = read32b(f);
	trk_ptr = read32b(f);
	smp_ptr = read32b(f);
	read32b(f);			/* total smp len */
	read32b(f);			/* unpacked trk size */

	fseek(f, start + sng_ptr, SEEK_SET);

	fread(m->name, 1, 32, f);
	seq_ptr = read32b(f);
	m->xxh->len = read16b(f);
	m->xxh->rst = read16b(f);
	m->xxh->bpm = read8(f);
	m->xxh->tpo = read8(f);
	read16b(f);			/* global volume */
	read8(f);			/* master L */
	read8(f);			/* master R */

	for (i = 0; i < m->xxh->chn; i++) {
		read16b(f);		/* pan */
	}
	
	MODULE_INFO();

	/* Sequence */

	fseek(f, start + seq_ptr, SEEK_SET);
	for (i = 0; i < m->xxh->len; i++)
		m->xxo[i] = read16b(f);

	/* Instruments */

	INSTRUMENT_INIT();

	fseek(f, start + ins_ptr, SEEK_SET);
	reportv(ctx, 1, "     Name                             Len  LBeg LEnd L Vol C2Spd\n");

	for (i = 0; i < m->xxh->ins; i++) {
		int c2spd, flags;

		m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1);

		fread(m->xxih[i].name, 1, 32, f);
		sdata[i] = read32b(f);
		m->xxs[i].len = read32b(f);
		m->xxs[i].lps = read32b(f);
		m->xxs[i].lpe = m->xxs[i].lps + read32b(f);
		read32b(f);
		read32b(f);
		c2spd = read32b(f);
		c2spd_to_note(c2spd, &m->xxi[i][0].xpo, &m->xxi[i][0].fin);
		m->xxi[i][0].vol = read16b(f) >> 4;
		read8(f);		/* vol L */
		read8(f);		/* vol R */
		m->xxi[i][0].pan = 0x80;
		flags = read8(f);
		m->xxs[i].flg = flags & 0x03 ? WAVE_LOOPING : 0;
		m->xxs[i].flg |= flags & 0x02 ? WAVE_BIDIR_LOOP : 0;
		m->xxi[i][0].fin += 0 * read8(f);	// FIXME
		read8(f);		/* unused */
		read8(f);
		read8(f);
		read8(f);
		read16b(f);
		read32b(f);
		read32b(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 %5d\n",
				i, m->xxih[i].name,
				m->xxs[i].len, m->xxs[i].lps, m->xxs[i].lpe,
				m->xxs[i].flg & WAVE_BIDIR_LOOP ? 'B' :
					m->xxs[i].flg & WAVE_LOOPING ? 'L' : ' ',
				m->xxi[i][0].vol, c2spd);
		}
	}

	/* PATTERN_INIT - alloc extra track*/
	PATTERN_INIT();

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

	/* Tracks */

	for (i = 1; i < m->xxh->trk; i++) {
		int offset, rows;
		uint8 b;

		fseek(f, start + trk_ptr + i * 4, SEEK_SET);
		offset = read32b(f);
		fseek(f, start + offset, SEEK_SET);

		rows = read16b(f);
		m->xxt[i] = calloc(sizeof(struct xxm_track) +
				sizeof(struct xxm_event) * rows, 1);
		m->xxt[i]->rows = rows;

		//printf("\n=== Track %d ===\n\n", i);
		for (j = 0; j < rows; j++) {
			uint8 note, f2p;

			b = read8(f);
			j += b & 0x03;

			note = 0;
			event = &m->xxt[i]->event[j];
			if (b & 0x04)
				note = read8(f);
			if (b & 0x08)
				event->ins = read8(f);
			if (b & 0x10)
				event->vol = read8(f);
			if (b & 0x20)
				event->fxt = read8(f);
			if (b & 0x40)
				event->fxp = read8(f);
			if (b & 0x80)
				f2p = read8(f);

			if (note == 1)
				event->note = XMP_KEY_OFF;
			else if (note > 11) /* adjusted to play codeine.mgt */
				event->note = note - 11;

			/* effects */
			if (event->fxt < 0x10)
				/* like amiga */ ;
			else switch (event->fxt) {
			case 0x13: 
			case 0x14: 
			case 0x15: 
			case 0x17: 
			case 0x1c: 
			case 0x1d: 
			case 0x1e: 
				event->fxt = FX_EXTENDED;
				event->fxp = ((event->fxt & 0x0f) << 4) |
							(event->fxp & 0x0f);
				break;
			default:
				event->fxt = event->fxp = 0;
			}

			/* volume and volume column effects */
			if ((event->vol >= 0x10) && (event->vol <= 0x50)) {
				event->vol -= 0x0f;
				continue;
			}

			switch (event->vol >> 4) {
			case 0x06:	/* Volume slide down */
				event->f2t = FX_VOLSLIDE_2;
				event->f2p = event->vol - 0x60;
				break;
			case 0x07:	/* Volume slide up */
				event->f2t = FX_VOLSLIDE_2;
				event->f2p = (event->vol - 0x70) << 4;
				break;
			case 0x08:	/* Fine volume slide down */
				event->f2t = FX_EXTENDED;
				event->f2p = (EX_F_VSLIDE_DN << 4) |
							(event->vol - 0x80);
				break;
			case 0x09:	/* Fine volume slide up */
				event->f2t = FX_EXTENDED;
				event->f2p = (EX_F_VSLIDE_UP << 4) |
							(event->vol - 0x90);
				break;
			case 0x0a:	/* Set vibrato speed */
				event->f2t = FX_VIBRATO;
				event->f2p = (event->vol - 0xa0) << 4;
				break;
			case 0x0b:	/* Vibrato */
				event->f2t = FX_VIBRATO;
				event->f2p = event->vol - 0xb0;
				break;
			case 0x0c:	/* Set panning */
				event->f2t = FX_SETPAN;
				event->f2p = ((event->vol - 0xc0) << 4) + 8;
				break;
			case 0x0d:	/* Pan slide left */
				event->f2t = FX_PANSLIDE;
				event->f2p = (event->vol - 0xd0) << 4;
				break;
			case 0x0e:	/* Pan slide right */
				event->f2t = FX_PANSLIDE;
				event->f2p = event->vol - 0xe0;
				break;
			case 0x0f:	/* Tone portamento */
				event->f2t = FX_TONEPORTA;
				event->f2p = (event->vol - 0xf0) << 4;
				break;
			}
	
			event->vol = 0;

			/*printf("%02x  %02x %02x %02x %02x %02x\n",
				j, event->note, event->ins, event->vol,
				event->fxt, event->fxp);*/
		}

		if (V(0) && i % m->xxh->chn == 0)
			report(".");
	}
	reportv(ctx, 0, "\n");

	/* Extra track */
	m->xxt[0] = calloc(sizeof(struct xxm_track) +
			sizeof(struct xxm_event) * 64 - 1, 1);
	m->xxt[0]->rows = 64;

	/* Read and convert patterns */

	reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat);
	fseek(f, start + pat_ptr, SEEK_SET);

	for (i = 0; i < m->xxh->pat; i++) {
		PATTERN_ALLOC(i);

		m->xxp[i]->rows = read16b(f);
		for (j = 0; j < m->xxh->chn; j++) {
			m->xxp[i]->info[j].index = read16b(f) - 1;
			//printf("%3d ", m->xxp[i]->info[j].index);
		}

		reportv(ctx, 0, ".");
		//printf("\n");
	}
	reportv(ctx, 0, "\n");

	/* Read samples */

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

	for (i = 0; i < m->xxh->ins; i++) {
		if (m->xxih[i].nsm == 0)
			continue;

		fseek(f, start + sdata[i], SEEK_SET);
		xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, 0,
						&m->xxs[m->xxi[i][0].sid], NULL);
		reportv(ctx, 0, ".");
	}
	reportv(ctx, 0, "\n");

	return 0;
}
static int med3_load(struct xmp_context *ctx, FILE *f, const int start)
{
	struct xmp_player_context *p = &ctx->p;
	struct xmp_mod_context *m = &p->m;
	int i, j;
	uint32 mask;
	int transp, sliding;

	LOAD_INIT();

	read32b(f);

	strcpy(m->type, "MED3 (MED 2.00)");

	m->xxh->ins = m->xxh->smp = 32;
	INSTRUMENT_INIT();

	/* read instrument names */
	for (i = 0; i < 32; i++) {
		uint8 c, buf[40];
		for (j = 0; j < 40; j++) {
			c = read8(f);
			buf[j] = c;
			if (c == 0)
				break;
		}
		copy_adjust(m->xxih[i].name, buf, 32);
		m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1);
	}

	/* read instrument volumes */
	mask = read32b(f);
	for (i = 0; i < 32; i++, mask <<= 1) {
		m->xxi[i][0].vol = mask & MASK ? read8(f) : 0;
		m->xxi[i][0].pan = 0x80;
		m->xxi[i][0].fin = 0;
		m->xxi[i][0].sid = i;
	}

	/* read instrument loops */
	mask = read32b(f);
	for (i = 0; i < 32; i++, mask <<= 1) {
		m->xxs[i].lps = mask & MASK ? read16b(f) : 0;
	}

	/* read instrument loop length */
	mask = read32b(f);
	for (i = 0; i < 32; i++, mask <<= 1) {
		uint32 lsiz = mask & MASK ? read16b(f) : 0;
		m->xxs[i].len = m->xxs[i].lps + lsiz;
		m->xxs[i].lpe = m->xxs[i].lps + lsiz;
		m->xxs[i].flg = lsiz > 1 ? WAVE_LOOPING : 0;
	}

	m->xxh->chn = 4;
	m->xxh->pat = read16b(f);
	m->xxh->trk = m->xxh->chn * m->xxh->pat;

	m->xxh->len = read16b(f);
	fread(m->xxo, 1, m->xxh->len, f);
	m->xxh->tpo = read16b(f);
	if (m->xxh->tpo > 10) {
		m->xxh->bpm = 125 * m->xxh->tpo / 33;
		m->xxh->tpo = 6;
	}
	transp = read8s(f);
	read8(f);			/* flags */
	sliding = read16b(f);		/* sliding */
	read32b(f);			/* jumping mask */
	fseek(f, 16, SEEK_CUR);		/* rgb */

	/* read midi channels */
	mask = read32b(f);
	for (i = 0; i < 32; i++, mask <<= 1) {
		if (mask & MASK)
			read8(f);
	}

	/* read midi programs */
	mask = read32b(f);
	for (i = 0; i < 32; i++, mask <<= 1) {
		if (mask & MASK)
			read8(f);
	}
	
	MODULE_INFO();

	reportv(ctx, 0, "Sliding        : %d\n", sliding);
	reportv(ctx, 0, "Play transpose : %d semitones\n", transp);

	if (sliding == 6)
		m->quirk |= XMP_QRK_VSALL | XMP_QRK_PBALL;

	for (i = 0; i < 32; i++)
		m->xxi[i][0].xpo = transp;

	PATTERN_INIT();

	/* Load and convert patterns */
	reportv(ctx, 0, "Stored patterns: %d ", m->xxh->pat);

	for (i = 0; i < m->xxh->pat; i++) {
		uint32 *conv;
		uint8 b, tracks;
		uint16 convsz;

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

		tracks = read8(f);

		b = read8(f);
		convsz = read16b(f);
		conv = calloc(1, convsz + 16);
		assert(conv);

                if (b & M0F_LINEMSK00)
			*conv = 0L;
                else if (b & M0F_LINEMSK0F)
			*conv = 0xffffffff;
                else
			*conv = read32b(f);

                if (b & M0F_LINEMSK10)
			*(conv + 1) = 0L;
                else if (b & M0F_LINEMSK1F)
			*(conv + 1) = 0xffffffff;
                else
			*(conv + 1) = read32b(f);

                if (b & M0F_FXMSK00)
			*(conv + 2) = 0L;
                else if (b & M0F_FXMSK0F)
			*(conv + 2) = 0xffffffff;
                else
			*(conv + 2) = read32b(f);

                if (b & M0F_FXMSK10)
			*(conv + 3) = 0L;
                else if (b & M0F_FXMSK1F)
			*(conv + 3) = 0xffffffff;
                else
			*(conv + 3) = read32b(f);

		fread(conv + 4, 1, convsz, f);

                unpack_block(ctx, i, (uint8 *)conv);

		free(conv);

		reportv(ctx, 0, ".");
	}
	reportv(ctx, 0, "\n");

	/* Load samples */

	reportv(ctx, 0, "Instruments    : %d ", m->xxh->ins);
	reportv(ctx, 1, "\n     Instrument name                  Len  LBeg LEnd L Vol");

	mask = read32b(f);
	for (i = 0; i < 32; i++, mask <<= 1) {
		if (~mask & MASK)
			continue;

		m->xxs[i].len = read32b(f);
		if (read16b(f))		/* type */
			continue;

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

		reportv(ctx, 1, "\n[%2X] %-32.32s %04x %04x %04x %c V%02x ",
			i, m->xxih[i].name, m->xxs[i].len, m->xxs[i].lps,
			m->xxs[i].lpe,
			m->xxs[i].flg & WAVE_LOOPING ? 'L' : ' ',
			m->xxi[i][0].vol);

		xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, 0,
				  &m->xxs[m->xxi[i][0].sid], NULL);
		reportv(ctx, 0, ".");
	}
	reportv(ctx, 0, "\n");

	return 0;
}
static int far_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, vib = 0;
    struct xxm_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 */

    m->xxh->chn = 16;
    /*m->xxh->pat=ffh2.patterns; (Error in specs? --claudio) */
    m->xxh->len = ffh2.songlen;
    m->xxh->tpo = 6;
    m->xxh->bpm = 8 * 60 / ffh.tempo;
    memcpy (m->xxo, ffh2.order, m->xxh->len);

    for (m->xxh->pat = i = 0; i < 256; i++) {
	if (ffh2.patsize[i])
	    m->xxh->pat = i + 1;
    }

    m->xxh->trk = m->xxh->chn * m->xxh->pat;

    strncpy(m->name, (char *)ffh.name, 40);
    sprintf(m->type, "FAR (Farandole Composer %d.%d)",
				MSN(ffh.version), LSN(ffh.version));

    MODULE_INFO();

    PATTERN_INIT();

    /* Read and convert patterns */
    if (V(0)) {
	report("Comment bytes  : %d\n", ffh.textlen);
	report("Stored patterns: %d ", m->xxh->pat);
    }

    for (i = 0; i < m->xxh->pat; i++) {
	uint8 brk, note, ins, vol, fxb;

	PATTERN_ALLOC(i);
	if (!ffh2.patsize[i])
	    continue;
	m->xxp[i]->rows = (ffh2.patsize[i] - 2) / 64;
	TRACK_ALLOC(i);

	brk = read8(f) + 1;
	read8(f);

	for (j = 0; j < m->xxp[i]->rows * m->xxh->chn; j++) {
	    event = &EVENT(i, j % m->xxh->chn, j / m->xxh->chn);

	    if ((j % m->xxh->chn) == 0 && (j / m->xxh->chn) == brk)
		event->f2t = FX_BREAK;
	
	    note = read8(f);
	    ins = read8(f);
	    vol = read8(f);
	    fxb = read8(f);

	    if (note)
		event->note = note + 36;
	    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_TEMPO:
		event->fxp = 8 * 60 / event->fxp;
		break;
	    }
	}
	reportv(ctx, 0, ".");
    }

    m->xxh->ins = -1;
    fread(sample_map, 1, 8, f);
    for (i = 0; i < 64; i++) {
	if (sample_map[i / 8] & (1 << (i % 8)))
		m->xxh->ins = i;
    }
    m->xxh->ins++;

    m->xxh->smp = m->xxh->ins;

    INSTRUMENT_INIT();

    /* Read and convert instruments and samples */
    reportv(ctx, 0, "\nInstruments    : %d ", m->xxh->ins);

    for (i = 0; i < m->xxh->ins; i++) {
	if (!(sample_map[i / 8] & (1 << (i % 8))))
		continue;

	m->xxi[i] = calloc (sizeof (struct xxm_instrument), 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;
	m->xxih[i].nsm = !!(m->xxs[i].len = fih.length);
	m->xxs[i].lps = fih.loop_start;
	m->xxs[i].lpe = fih.loopend;
	m->xxs[i].flg = fih.sampletype ? WAVE_16_BITS : 0;
	m->xxs[i].flg |= fih.loopmode ? WAVE_LOOPING : 0;
	m->xxi[i][0].vol = 0xff; /* fih.volume; */
	m->xxi[i][0].sid = i;

	copy_adjust(m->xxih[i].name, fih.name, 32);

	if (V(1) && (strlen((char *)m->xxih[i].name) || m->xxs[i].len) && m->xxs[i].lps != 0xffff) {
	    report ("\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,
			fih.loopmode ? 'L' : ' ', m->xxi[i][0].vol);
	    reportv(ctx, 0, ".");
	}
	xmp_drv_loadpatch(ctx, f, m->xxi[i][0].sid, m->c4rate, 0, &m->xxs[i], NULL);
    }
    reportv(ctx, 0, "\n");

    m->volbase = 0xff;

    return 0;
}
Ejemplo n.º 7
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;
}