Exemple #1
0
static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	int i, j, r;
	struct xmp_event *event;
	struct ObjectHeader oh;
	struct RTMMHeader rh;
	struct RTNDHeader rp;
	struct RTINHeader ri;
	struct RTSMHeader rs;
	int offset, smpnum, version;
	char tracker_name[21], composer[33];

	LOAD_INIT();

	if (read_object_header(f, &oh, "RTMM") < 0)
		return -1;

	version = oh.version;

	hio_read(tracker_name, 1, 20, f);
	tracker_name[20] = 0;
	hio_read(composer, 1, 32, f);
	composer[32] = 0;
	rh.flags = hio_read16l(f);	/* bit 0: linear table, bit 1: track names */
	rh.ntrack = hio_read8(f);
	rh.ninstr = hio_read8(f);
	rh.nposition = hio_read16l(f);
	rh.npattern = hio_read16l(f);
	rh.speed = hio_read8(f);
	rh.tempo = hio_read8(f);
	hio_read(&rh.panning, 32, 1, f);
	rh.extraDataSize = hio_read32l(f);

	/* Sanity check */
	if (rh.nposition > 255 || rh.ntrack > 32 || rh.npattern > 255) {
		return -1;
	}

	if (version >= 0x0112)
		hio_seek(f, 32, SEEK_CUR);		/* skip original name */

	for (i = 0; i < rh.nposition; i++) {
		mod->xxo[i] = hio_read16l(f);
		if (mod->xxo[i] >= rh.npattern) {
			return -1;
		}
	}
	
	strncpy(mod->name, oh.name, 20);
	snprintf(mod->type, XMP_NAME_SIZE, "%s RTM %x.%02x",
				tracker_name, version >> 8, version & 0xff);
	/* strncpy(m->author, composer, XMP_NAME_SIZE); */

	mod->len = rh.nposition;
	mod->pat = rh.npattern;
	mod->chn = rh.ntrack;
	mod->trk = mod->chn * mod->pat;
	mod->ins = rh.ninstr;
	mod->spd = rh.speed;
	mod->bpm = rh.tempo;

	m->c4rate = C4_NTSC_RATE;
	m->period_type = rh.flags & 0x01 ? PERIOD_LINEAR : PERIOD_AMIGA;

	MODULE_INFO();

	for (i = 0; i < mod->chn; i++)
		mod->xxc[i].pan = rh.panning[i] & 0xff;

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	D_(D_INFO "Stored patterns: %d", mod->pat);

	offset = 42 + oh.headerSize + rh.extraDataSize;

	for (i = 0; i < mod->pat; i++) {
		uint8 c;

		hio_seek(f, start + offset, SEEK_SET);

		if (read_object_header(f, &oh, "RTND") < 0) {
			D_(D_CRIT "Error reading pattern %d", i);
			return -1;
		}
	
		rp.flags = hio_read16l(f);
		rp.ntrack = hio_read8(f);
		rp.nrows = hio_read16l(f);
		rp.datasize = hio_read32l(f);

		/* Sanity check */
		if (rp.ntrack > rh.ntrack || rp.nrows > 256) {
			return -1;
		}

		offset += 42 + oh.headerSize + rp.datasize;

		if (libxmp_alloc_pattern_tracks(mod, i, rp.nrows) < 0)
			return -1;

		for (r = 0; r < rp.nrows; r++) {
			for (j = 0; /*j < rp.ntrack */; j++) {

				c = hio_read8(f);
				if (c == 0)		/* next row */
					break;

				/* Sanity check */
				if (j >= rp.ntrack) {
					return -1;
				}

				event = &EVENT(i, j, r);

				if (c & 0x01) {		/* set track */
					j = hio_read8(f);

					/* Sanity check */
					if (j >= rp.ntrack) {
						return -1;
					}

					event = &EVENT(i, j, r);
				}
				if (c & 0x02) {		/* read note */
					event->note = hio_read8(f) + 1;
					if (event->note == 0xff) {
						event->note = XMP_KEY_OFF;
					} else {
						event->note += 12;
					}
				}
				if (c & 0x04)		/* read instrument */
					event->ins = hio_read8(f);
				if (c & 0x08)		/* read effect */
					event->fxt = hio_read8(f);
				if (c & 0x10)		/* read parameter */
					event->fxp = hio_read8(f);
				if (c & 0x20)		/* read effect 2 */
					event->f2t = hio_read8(f);
				if (c & 0x40)		/* read parameter 2 */
					event->f2p = hio_read8(f);
			}
		}
	}

	/*
	 * load instruments
	 */

	D_(D_INFO "Instruments: %d", mod->ins);

	hio_seek(f, start + offset, SEEK_SET);

	/* ESTIMATED value! We don't know the actual value at this point */
	mod->smp = MAX_SAMP;

	if (libxmp_init_instrument(m) < 0)
		return -1;

	smpnum = 0;
	for (i = 0; i < mod->ins; i++) {
		struct xmp_instrument *xxi = &mod->xxi[i];

		if (read_object_header(f, &oh, "RTIN") < 0) {
			D_(D_CRIT "Error reading instrument %d", i);
			return -1;
		}

		libxmp_instrument_name(mod, i, (uint8 *)&oh.name, 32);

		if (oh.headerSize == 0) {
			D_(D_INFO "[%2X] %-26.26s %2d ", i,
						xxi->name, xxi->nsm);
			ri.nsample = 0;
			continue;
		}

		ri.nsample = hio_read8(f);
		ri.flags = hio_read16l(f);	/* bit 0 : default panning enabled */
		if (hio_read(&ri.table, 1, 120, f) != 120)
			return -1;

		ri.volumeEnv.npoint = hio_read8(f);

		/* Sanity check */
		if (ri.volumeEnv.npoint >= 12)
			return -1;

		for (j = 0; j < 12; j++) {
			ri.volumeEnv.point[j].x = hio_read32l(f);
			ri.volumeEnv.point[j].y = hio_read32l(f);
		}
		ri.volumeEnv.sustain = hio_read8(f);
		ri.volumeEnv.loopstart = hio_read8(f);
		ri.volumeEnv.loopend = hio_read8(f);
		ri.volumeEnv.flags = hio_read16l(f); /* bit 0:enable 1:sus 2:loop */
		
		ri.panningEnv.npoint = hio_read8(f);

		/* Sanity check */
		if (ri.panningEnv.npoint >= 12)
			return -1;

		for (j = 0; j < 12; j++) {
			ri.panningEnv.point[j].x = hio_read32l(f);
			ri.panningEnv.point[j].y = hio_read32l(f);
		}
		ri.panningEnv.sustain = hio_read8(f);
		ri.panningEnv.loopstart = hio_read8(f);
		ri.panningEnv.loopend = hio_read8(f);
		ri.panningEnv.flags = hio_read16l(f);

		ri.vibflg = hio_read8(f);
		ri.vibsweep = hio_read8(f);
		ri.vibdepth = hio_read8(f);
		ri.vibrate = hio_read8(f);
		ri.volfade = hio_read16l(f);

		if (version >= 0x0110) {
			ri.midiPort = hio_read8(f);
			ri.midiChannel = hio_read8(f);
			ri.midiProgram = hio_read8(f);
			ri.midiEnable = hio_read8(f);
		}
		if (version >= 0x0112) {
			ri.midiTranspose = hio_read8(f);
			ri.midiBenderRange = hio_read8(f);
			ri.midiBaseVolume = hio_read8(f);
			ri.midiUseVelocity = hio_read8(f);
		}

		xxi->nsm = ri.nsample;

		D_(D_INFO "[%2X] %-26.26s %2d", i, xxi->name, xxi->nsm);

		if (xxi->nsm > 16)
			xxi->nsm = 16;

		if (libxmp_alloc_subinstrument(mod, i, xxi->nsm) < 0)
			return -1;

		for (j = 0; j < 120; j++)
			xxi->map[j].ins = ri.table[j];

		/* Envelope */
		xxi->rls = ri.volfade;
		xxi->aei.npt = ri.volumeEnv.npoint;
		xxi->aei.sus = ri.volumeEnv.sustain;
		xxi->aei.lps = ri.volumeEnv.loopstart;
		xxi->aei.lpe = ri.volumeEnv.loopend;
		xxi->aei.flg = ri.volumeEnv.flags;
		xxi->pei.npt = ri.panningEnv.npoint;
		xxi->pei.sus = ri.panningEnv.sustain;
		xxi->pei.lps = ri.panningEnv.loopstart;
		xxi->pei.lpe = ri.panningEnv.loopend;
		xxi->pei.flg = ri.panningEnv.flags;

		for (j = 0; j < xxi->aei.npt; j++) {
			xxi->aei.data[j * 2 + 0] = ri.volumeEnv.point[j].x;
			xxi->aei.data[j * 2 + 1] = ri.volumeEnv.point[j].y / 2;
		}
		for (j = 0; j < xxi->pei.npt; j++) {
			xxi->pei.data[j * 2 + 0] = ri.panningEnv.point[j].x;
			xxi->pei.data[j * 2 + 1] = 32 + ri.panningEnv.point[j].y / 2;
		}

		/* For each sample */
		for (j = 0; j < xxi->nsm; j++, smpnum++) {
			struct xmp_subinstrument *sub = &xxi->sub[j];
			struct xmp_sample *xxs;

			if (read_object_header(f, &oh, "RTSM") < 0) {
				D_(D_CRIT "Error reading sample %d", j);
				return -1;
			}

			rs.flags = hio_read16l(f);
			rs.basevolume = hio_read8(f);
			rs.defaultvolume = hio_read8(f);
			rs.length = hio_read32l(f);
			rs.loop = hio_read32l(f);
			rs.loopbegin = hio_read32l(f);
			rs.loopend = hio_read32l(f);
			rs.basefreq = hio_read32l(f);
			rs.basenote = hio_read8(f);
			rs.panning = hio_read8(f);

			libxmp_c2spd_to_note(rs.basefreq, &sub->xpo, &sub->fin);
			sub->xpo += 48 - rs.basenote;
			sub->vol = rs.defaultvolume * rs.basevolume / 0x40;
			sub->pan = 0x80 + rs.panning * 2;
			sub->vwf = ri.vibflg;
			sub->vde = ri.vibdepth << 2;
			sub->vra = ri.vibrate;
			sub->vsw = ri.vibsweep;
			sub->sid = smpnum;

			if (smpnum >= mod->smp) {
				 mod->xxs = libxmp_realloc_samples(mod->xxs,
						&mod->smp, mod->smp * 3 / 2);
				if (mod->xxs == NULL)
					return -1;
			}
 			xxs = &mod->xxs[smpnum];

			libxmp_copy_adjust(xxs->name, (uint8 *)oh.name, 31);

			xxs->len = rs.length;
			xxs->lps = rs.loopbegin;
			xxs->lpe = rs.loopend;

			xxs->flg = 0;
			if (rs.flags & 0x02) {
				xxs->flg |= XMP_SAMPLE_16BIT;
				xxs->len >>= 1;
				xxs->lps >>= 1;
				xxs->lpe >>= 1;
			}

			xxs->flg |= rs.loop & 0x03 ?  XMP_SAMPLE_LOOP : 0;
			xxs->flg |= rs.loop == 2 ? XMP_SAMPLE_LOOP_BIDIR : 0;

			D_(D_INFO "  [%1x] %05x%c%05x %05x %c "
						"V%02x F%+04d P%02x R%+03d",
				j, xxs->len,
				xxs->flg & XMP_SAMPLE_16BIT ? '+' : ' ',
				xxs->lps, xxs->lpe,
				xxs->flg & XMP_SAMPLE_LOOP_BIDIR ? 'B' :
				xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
				sub->vol, sub->fin, sub->pan, sub->xpo);

			if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF, xxs, NULL) < 0)
				return -1;
		}
	}
Exemple #2
0
static int coco_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j;
	int seq_ptr, pat_ptr, smp_ptr[100];

	LOAD_INIT();

	mod->chn = hio_read8(f) & 0x3f;
	libxmp_read_title(f, mod->name, 20);

	for (i = 0; i < 20; i++) {
		if (mod->name[i] == 0x0d)
			mod->name[i] = 0;
	}

	libxmp_set_type(m, "Coconizer");

	mod->ins = mod->smp = hio_read8(f);
	mod->len = hio_read8(f);
	mod->pat = hio_read8(f);
	mod->trk = mod->pat * mod->chn;

	seq_ptr = hio_read32l(f);
	pat_ptr = hio_read32l(f);

	MODULE_INFO();

	if (libxmp_init_instrument(m) < 0)
		return -1;

	m->vol_table = (int *)arch_vol_table;
	m->volbase = 0xff;

	for (i = 0; i < mod->ins; i++) {
		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		smp_ptr[i] = hio_read32l(f);
		mod->xxs[i].len = hio_read32l(f);
		mod->xxi[i].sub[0].vol = 0xff - hio_read32l(f);
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxs[i].lps = hio_read32l(f);
                mod->xxs[i].lpe = mod->xxs[i].lps + hio_read32l(f);
		if (mod->xxs[i].lpe)
			mod->xxs[i].lpe -= 1;
		mod->xxs[i].flg = mod->xxs[i].lps > 0 ?  XMP_SAMPLE_LOOP : 0;
		hio_read(mod->xxi[i].name, 1, 11, f);
		for (j = 0; j < 11; j++) {
			if (mod->xxi[i].name[j] == 0x0d)
				mod->xxi[i].name[j] = 0;
		}
		hio_read8(f);	/* unused */
		mod->xxi[i].sub[0].sid = i;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		D_(D_INFO "[%2X] %-10.10s  %05x %05x %05x %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);
	}

	/* Sequence */

	hio_seek(f, start + seq_ptr, SEEK_SET);
	for (i = 0; ; i++) {
		uint8 x = hio_read8(f);
		if (x == 0xff)
			break;
		mod->xxo[i] = x;
	}
	for (i++; i % 4; i++)	/* for alignment */
		hio_read8(f);


	/* Patterns */

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	D_(D_INFO "Stored patterns: %d", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < (64 * mod->chn); j++) {
			event = &EVENT (i, j % mod->chn, j / mod->chn);
			event->fxp = hio_read8(f);
			event->fxt = hio_read8(f);
			event->ins = hio_read8(f);
			event->note = hio_read8(f);
			if (event->note)
				event->note += 12;

			fix_effect(event);
		}
	}

	/* Read samples */

	D_(D_INFO "Stored samples : %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		if (mod->xxi[i].nsm == 0)
			continue;

		hio_seek(f, start + smp_ptr[i], SEEK_SET);
		if (libxmp_load_sample(m, f, SAMPLE_FLAG_VIDC, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	for (i = 0; i < mod->chn; i++) {
		mod->xxc[i].pan = DEFPAN((((i + 3) / 2) % 2) * 0xff);
	}

	return 0;
}
Exemple #3
0
static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event, dummy;
	int i, len, chan;
	int rows, r;
	uint8 flag;
	
	i = hio_read8(f);	/* pattern number */
	len = hio_read32l(f);
	
	rows = hio_read8(f) + 1;

	if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
		return -1;

	for (r = 0; r < rows; ) {
		if ((flag = hio_read8(f)) == 0) {
			r++;
			continue;
		}

		chan = flag & 0x1f;

		event = chan < mod->chn ? &EVENT(i, chan, r) : &dummy;

		if (flag & 0x80) {
			uint8 fxp = hio_read8(f);
			uint8 fxt = hio_read8(f);

			switch (fxt) {
			case 0x14:		/* speed */
				fxt = FX_S3M_SPEED;
				break;
			default:
				if (fxt > 0x0f) {
					printf("unknown effect %02x %02x\n", fxt, fxp);
					fxt = fxp = 0;
				}
			}

			event->fxt = fxt;
			event->fxp = fxp;
		}

		if (flag & 0x40) {
			event->ins = hio_read8(f);
			event->note = hio_read8(f);

			if (event->note == 128) {
				event->note = XMP_KEY_OFF;
			}
		}

		if (flag & 0x20) {
			event->vol = 1 + hio_read8(f) / 2;
		}
	}

	return 0;
}
Exemple #4
0
static int gal5_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	iff_handle handle;
	int i, ret, offset;
	struct local_data data;

	LOAD_INIT();

	hio_read32b(f);	/* Skip RIFF */
	hio_read32b(f);	/* Skip size */
	hio_read32b(f);	/* Skip AM   */

	offset = hio_tell(f);

	mod->smp = mod->ins = 0;

	handle = libxmp_iff_new();
	if (handle == NULL)
		return -1;

	m->c4rate = C4_NTSC_RATE;

	/* IFF chunk IDs */
	ret = libxmp_iff_register(handle, "INIT", get_init);		/* Galaxy 5.0 */
	ret |= libxmp_iff_register(handle, "ORDR", get_ordr);
	ret |= libxmp_iff_register(handle, "PATT", get_patt_cnt);
	ret |= libxmp_iff_register(handle, "INST", get_inst_cnt);

	if (ret != 0)
		return -1;

	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
	libxmp_iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
	libxmp_iff_set_quirk(handle, IFF_CHUNK_ALIGN2);

	/* Load IFF chunks */
	if (libxmp_iff_load(handle, m, f, &data) < 0) {
		libxmp_iff_release(handle);
		return -1;
	}

	libxmp_iff_release(handle);

	mod->trk = mod->pat * mod->chn;
	mod->smp = mod->ins;

	MODULE_INFO();

	if (libxmp_init_instrument(m) < 0)
		return -1;

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	D_(D_INFO "Stored patterns: %d", mod->pat);
	D_(D_INFO "Stored samples: %d ", mod->smp);

	hio_seek(f, start + offset, SEEK_SET);

	handle = libxmp_iff_new();
	if (handle == NULL)
		return -1;

	/* IFF chunk IDs */
	ret = libxmp_iff_register(handle, "PATT", get_patt);
	ret |= libxmp_iff_register(handle, "INST", get_inst);

	if (ret != 0)
		return -1;

	libxmp_iff_set_quirk(handle, IFF_LITTLE_ENDIAN);
	libxmp_iff_set_quirk(handle, IFF_SKIP_EMBEDDED);
	libxmp_iff_set_quirk(handle, IFF_CHUNK_ALIGN2);

	/* Load IFF chunks */
	if (libxmp_iff_load(handle, m, f, &data) < 0) {
		libxmp_iff_release(handle);
		return -1;
	}

	libxmp_iff_release(handle);

	/* Alloc missing patterns */
	for (i = 0; i < mod->pat; i++) {
		if (mod->xxp[i] == NULL) {
			if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0) {
				return -1;
			}
		}
	}

	for (i = 0; i < mod->chn; i++) {
		mod->xxc[i].pan = data.chn_pan[i] * 2;
	}

	m->quirk |= QUIRKS_FT2;
	m->read_event_type = READ_EVENT_FT2;

	return 0;
}
Exemple #5
0
static int hsc_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int pat, i, r, c;
    struct xmp_event *event;
    uint8 *x, *sid, e[2], buf[128 * 12];

    LOAD_INIT();

    hio_read(buf, 1, 128 * 12, f);

    x = buf;
    for (i = 0; i < 128; i++, x += 12) {
	if (x[9] & ~0x3 || x[10] & ~0x3)	/* Test waveform register */
	    break;
	if (x[8] & ~0xf)			/* Test feedback & algorithm */
	    break;
    }

    mod->ins = i;

    hio_seek(f, start + 0, SEEK_SET);

    mod->chn = 9;
    mod->bpm = 135;
    mod->spd = 6;
    mod->smp = mod->ins;

    m->quirk |= QUIRK_LINEAR;

    libxmp_set_type(m, "HSC-Tracker");

    MODULE_INFO();

    /* Read instruments */
    if (libxmp_init_instrument(m) < 0)
	return -1;

    hio_read(buf, 1, 128 * 12, f);
    sid = buf;
    for (i = 0; i < mod->ins; i++, sid += 12) {
	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
	    return -1;

	mod->xxi[i].nsm = 1;
	mod->xxi[i].sub[0].vol = 0x40;
	mod->xxi[i].sub[0].fin = (int8)sid[11] / 4;
	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].xpo = 0;
	mod->xxi[i].sub[0].sid = i;
	mod->xxi[i].rls = LSN(sid[7]) * 32;	/* carrier release */

	if (libxmp_load_sample(m, f, SAMPLE_FLAG_ADLIB | SAMPLE_FLAG_HSC,
					&mod->xxs[i], (char *)sid) < 0)
		return -1;
    }

    /* Read orders */
    for (pat = i = 0; i < 51; i++) {
	mod->xxo[i] = hio_read8(f);
	if (mod->xxo[i] > 127)
	    break;			/* FIXME: jump line */
	if (mod->xxo[i] > pat)
	    pat = mod->xxo[i];
    }
    hio_seek(f, 50 - i, SEEK_CUR);
    mod->len = i;
    mod->pat = pat + 1;
    mod->trk = mod->pat * mod->chn;

    D_(D_INFO "Module length: %d", mod->len);
    D_(D_INFO "Instruments: %d", mod->ins);
    D_(D_INFO "Stored patterns: %d", mod->pat);

    if (libxmp_init_pattern(mod) < 0)
	return -1;

    /* Read and convert patterns */
    for (i = 0; i < mod->pat; i++) {
	int ins[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

	if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
	    return -1;

        for (r = 0; r < mod->xxp[i]->rows; r++) {
            for (c = 0; c < 9; c++) {
	        hio_read(e, 1, 2, f);
	        event = &EVENT (i, c, r);
		if (e[0] & 0x80) {
		    ins[c] = e[1] + 1;
		} else if (e[0] == 0x7f) {
		    event->note = XMP_KEY_OFF;
		} else if (e[0] > 0) {
		    event->note = e[0] + 25;
		    event->ins = ins[c];
		}

		event->fxt = 0;
		event->fxp = 0;

		if (e[1] == 0x01) {
		    event->fxt = 0x0d;
		    event->fxp = 0;
		}
	    }
	}
    }

    for (i = 0; i < mod->chn; i++) {
	mod->xxc[i].pan = 0x80;
	mod->xxc[i].flg = XMP_CHANNEL_SYNTH;
    }

    m->synth = &synth_adlib;

    return 0;
}
Exemple #6
0
static int psm_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;
	uint8 buf[1024];
	uint32 p_ord, p_chn, p_pat, p_ins;
	uint32 p_smp[64];
	int type, ver /*, mode*/;
 
	LOAD_INIT();

	hio_read32b(f);

	hio_read(buf, 1, 60, f);
	strncpy(mod->name, (char *)buf, 60);

	type = hio_read8(f);		/* song type */
	ver = hio_read8(f);		/* song version */
	/*mode =*/ hio_read8(f);	/* pattern version */

	if (type & 0x01)		/* song mode not supported */
		return -1;

	libxmp_set_type(m, "Protracker Studio PSM %d.%02d", MSN(ver), LSN(ver));

	mod->spd = hio_read8(f);
	mod->bpm = hio_read8(f);
	hio_read8(f);			/* master volume */
	hio_read16l(f);			/* song length */
	mod->len = hio_read16l(f);
	mod->pat = hio_read16l(f);
	mod->ins = hio_read16l(f);
	hio_read16l(f);			/* ignore channels to play */
	mod->chn = hio_read16l(f);	/* use channels to proceed */
	mod->smp = mod->ins;
	mod->trk = mod->pat * mod->chn;

	/* Sanity check */
	if (mod->len > 256 || mod->pat > 256 || mod->ins > 255 ||
	    mod->chn > XMP_MAX_CHANNELS) {
		return -1;
        }

	p_ord = hio_read32l(f);
	p_chn = hio_read32l(f);
	p_pat = hio_read32l(f);
	p_ins = hio_read32l(f);

	/* should be this way but fails with Silverball song 6 */
	//mod->flg |= ~type & 0x02 ? XXM_FLG_MODRNG : 0;

	m->c4rate = C4_NTSC_RATE;

	MODULE_INFO();

	hio_seek(f, start + p_ord, SEEK_SET);
	hio_read(mod->xxo, 1, mod->len, f);

	hio_seek(f, start + p_chn, SEEK_SET);
	hio_read(buf, 1, 16, f);

	if (libxmp_init_instrument(m) < 0)
		return -1;

	hio_seek(f, start + p_ins, SEEK_SET);
	for (i = 0; i < mod->ins; i++) {
		uint16 flags, c2spd;
		int finetune;

		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		hio_read(buf, 1, 13, f);	/* sample filename */
		hio_read(buf, 1, 24, f);	/* sample description */
		buf[24] = 0;			/* add string termination */
		strncpy((char *)mod->xxi[i].name, (char *)buf, 24);
		p_smp[i] = hio_read32l(f);
		hio_read32l(f);			/* memory location */
		hio_read16l(f);			/* sample number */
		flags = hio_read8(f);		/* sample type */
		mod->xxs[i].len = hio_read32l(f); 
		mod->xxs[i].lps = hio_read32l(f);
		mod->xxs[i].lpe = hio_read32l(f);
		finetune = (int8)(hio_read8(f) << 4);
		mod->xxi[i].sub[0].vol = hio_read8(f);
		c2spd = hio_read16l(f);
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;
		mod->xxs[i].flg = flags & 0x80 ? XMP_SAMPLE_LOOP : 0;
		mod->xxs[i].flg |= flags & 0x20 ? XMP_SAMPLE_LOOP_BIDIR : 0;

		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo,
						&mod->xxi[i].sub[0].fin);
		mod->xxi[i].sub[0].fin += finetune;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		D_(D_INFO "[%2X] %-22.22s %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, c2spd);
	}
	
	if (libxmp_init_pattern(mod) < 0)
		return -1;

	D_(D_INFO "Stored patterns: %d", mod->pat);

	hio_seek(f, start + p_pat, SEEK_SET);
	for (i = 0; i < mod->pat; i++) {
		int len;
		uint8 b, rows, chan;

		len = hio_read16l(f) - 4;
		rows = hio_read8(f);
		if (rows > 64) {
			return -1;
		}
		chan = hio_read8(f);
		if (chan > 32) {
			return -1;
		}

		if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
			return -1;

		for (r = 0; r < rows; r++) {
			while (len > 0) {
				b = hio_read8(f);
				len--;

				if (b == 0)
					break;
	
				c = b & 0x0f;
				if (c >= mod->chn)
					return -1;
				event = &EVENT(i, c, r);
	
				if (b & 0x80) {
					event->note = hio_read8(f) + 36 + 1;
					event->ins = hio_read8(f);
					len -= 2;
				}
	
				if (b & 0x40) {
					event->vol = hio_read8(f) + 1;
					len--;
				}
	
				if (b & 0x20) {
					event->fxt = hio_read8(f);
					event->fxp = hio_read8(f);
					len -= 2;
				}
			}
		}

		if (len > 0)
			hio_seek(f, len, SEEK_CUR);
	}

	/* Read samples */

	D_(D_INFO "Stored samples: %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		hio_seek(f, start + p_smp[i], SEEK_SET);
		if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF,
				&mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0)
			return -1;
	}

	return 0;
}
Exemple #7
0
static int mfp_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	int i, j, k, x, y;
	struct xmp_event *event;
	struct stat st;
	char smp_filename[PATH_MAX];
	HIO_HANDLE *s;
	int size1 /*, size2*/;
	int pat_addr, pat_table[128][4];
	uint8 buf[1024], mod_event[4];
	int row;

	LOAD_INIT();

	libxmp_set_type(m, "Magnetic Fields Packer");
	MODULE_INFO();

	mod->chn = 4;
	mod->ins = mod->smp = 31;

	if (libxmp_init_instrument(m) < 0)
		return -1;

	for (i = 0; i < 31; i++) {
		int loop_size;

		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;
		
		mod->xxs[i].len = 2 * hio_read16b(f);
		mod->xxi[i].sub[0].fin = (int8)(hio_read8(f) << 4);
		mod->xxi[i].sub[0].vol = hio_read8(f);
		mod->xxs[i].lps = 2 * hio_read16b(f);
		loop_size = hio_read16b(f);

		mod->xxs[i].lpe = mod->xxs[i].lps + 2 * loop_size;
		mod->xxs[i].flg = loop_size > 1 ? XMP_SAMPLE_LOOP : 0;
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;
		mod->xxi[i].rls = 0xfff;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

               	D_(D_INFO "[%2X] %04x %04x %04x %c V%02x %+d",
                       	i, mod->xxs[i].len, mod->xxs[i].lps,
                       	mod->xxs[i].lpe,
			loop_size > 1 ? 'L' : ' ',
                       	mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin >> 4);
	}

	mod->len = mod->pat = hio_read8(f);
	hio_read8(f);		/* restart */

	for (i = 0; i < 128; i++) {
		mod->xxo[i] = hio_read8(f);
	}

	if (hio_error(f)) {
		return -1;
	}

	mod->trk = mod->pat * mod->chn;

	/* Read and convert patterns */

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	size1 = hio_read16b(f);
	/* size2 = */ hio_read16b(f);

	for (i = 0; i < size1; i++) {		/* Read pattern table */
		for (j = 0; j < 4; j++) {
			pat_table[i][j] = hio_read16b(f);
		}
	}

	D_(D_INFO "Stored patterns: %d ", mod->pat);

	pat_addr = hio_tell(f);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < 4; j++) {
			hio_seek(f, pat_addr + pat_table[i][j], SEEK_SET);

			hio_read(buf, 1, 1024, f);

			for (row = k = 0; k < 4; k++) {
				for (x = 0; x < 4; x++) {
					for (y = 0; y < 4; y++, row++) {
						event = &EVENT(i, j, row);
						memcpy(mod_event, &buf[buf[buf[buf[k] + x] + y] * 2], 4);
						libxmp_decode_protracker_event(event, mod_event);
					}
				}
			}
		}
	}

	/* Read samples */
	D_(D_INFO "Loading samples: %d", mod->ins);

	/* first check smp.filename */
	if (strlen(m->basename) < 5 || m->basename[3] != '.') {
		fprintf(stderr, "libxmp: invalid filename %s\n", m->basename);
		goto err;
	}

	m->basename[0] = 's';
	m->basename[1] = 'm';
	m->basename[2] = 'p';
	snprintf(smp_filename, PATH_MAX, "%s%s", m->dirname, m->basename);
	if (stat(smp_filename, &st) < 0) {
		/* handle .set filenames like in Kid Chaos*/
		char *x;
		if (strchr(m->basename, '-')) {
			if ((x = strrchr(smp_filename, '-')))
				strcpy(x, ".set");
		}
		if (stat(smp_filename, &st) < 0) {
			fprintf(stderr, "libxmp: missing file %s\n",
								smp_filename);
			goto err;
		}
	}
	if ((s = hio_open(smp_filename, "rb")) == NULL) {
		fprintf(stderr, "libxmp: can't open sample file %s\n",
								smp_filename);
		goto err;
	}

	for (i = 0; i < mod->ins; i++) {
		if (libxmp_load_sample(m, s, SAMPLE_FLAG_FULLREP,
				&mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0) {
			free(s);
			return -1;
		}
	}

	hio_close(s);

	m->period_type = PERIOD_MODRNG;

	return 0;

    err:
	for (i = 0; i < mod->ins; i++) {
		mod->xxi[i].nsm = 0;
		memset(&mod->xxs[i], 0, sizeof(struct xmp_sample));
	}

	return 0;
}
Exemple #8
0
static int mtp_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j, k;
	uint8 buffer[25];
	int blocksize;

	LOAD_INIT();

	hio_read(buffer, 6, 1, f);

	if (!memcmp(buffer, "SONGOK", 6))
		libxmp_set_type(m, "IIgs SoundSmith");
	else if (!memcmp(buffer, "IAN92a", 8))
		libxmp_set_type(m, "IIgs MegaTracker");
	else
		return -1;

	blocksize = hio_read16l(f);
	mod->spd = hio_read16l(f);
	hio_seek(f, 10, SEEK_CUR);		/* skip 10 reserved bytes */
	
	mod->ins = mod->smp = 15;
	if (libxmp_init_instrument(m) < 0)
		return -1;

	for (i = 0; i < mod->ins; i++) {
		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		hio_read(buffer, 1, 22, f);
		if (buffer[0]) {
			buffer[buffer[0] + 1] = 0;
			libxmp_instrument_name(mod, i, buffer + 1, 22);
		}
		hio_read16l(f);		/* skip 2 reserved bytes */
		mod->xxi[i].sub[0].vol = hio_read8(f) >> 2;
		mod->xxi[i].sub[0].pan = 0x80;
		hio_seek(f, 5, SEEK_CUR);	/* skip 5 bytes */
	}

	mod->len = hio_read8(f) & 0x7f;
	hio_read8(f);
	hio_read(mod->xxo, 1, 128, f);

	MODULE_INFO();

	hio_seek(f, start + 600, SEEK_SET);

	mod->chn = 14;
	mod->pat = blocksize / (14 * 64);
	mod->trk = mod->pat * mod->chn;

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	/* Read and convert patterns */
	D_(D_INFO "Stored patterns: %d", mod->pat);

	/* Load notes */
	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < mod->xxp[i]->rows; j++) {
			for (k = 0; k < mod->chn; k++) {
				event = &EVENT(i, k, j);
				event->note = hio_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 = hio_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 = hio_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++) {
		HIO_HANDLE *s;
		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 = hio_open_file(filename, "rb")) != NULL) {
			asif_load(m, s, i);
			hio_close(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;
}
Exemple #9
0
static int pw_load(struct module_data *m, HIO_HANDLE *h, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	struct mod_header mh;
	uint8 mod_event[4];
	HIO_HANDLE *f;
	FILE *temp;
	char *name;
	char *temp_name;
	int i, j;

	/* Prowizard depacking */

	if ((temp = make_temp_file(&temp_name)) == NULL) {
		goto err;
	}

	if (pw_wizardry(h, temp, &name) < 0) {
		fclose(temp);
		goto err2;
	}
	
	/* Module loading */

	if ((f = hio_open_file(temp)) == NULL) {
		goto err2;
	}

	if (hio_seek(f, 0, start) < 0) {
		goto err3;
	}

	hio_read(&mh.name, 20, 1, f);
	for (i = 0; i < 31; i++) {
		hio_read(&mh.ins[i].name, 22, 1, f);
		mh.ins[i].size = hio_read16b(f);
		mh.ins[i].finetune = hio_read8(f);
		mh.ins[i].volume = hio_read8(f);
		mh.ins[i].loop_start = hio_read16b(f);
		mh.ins[i].loop_size = hio_read16b(f);
	}
	mh.len = hio_read8(f);
	mh.restart = hio_read8(f);
	hio_read(&mh.order, 128, 1, f);
	hio_read(&mh.magic, 4, 1, f);

	if (memcmp(mh.magic, "M.K.", 4)) {
		goto err3;
	}
		
	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;

	snprintf(mod->name, XMP_NAME_SIZE, "%s", (char *)mh.name);
	snprintf(mod->type, XMP_NAME_SIZE, "%s", name);
	MODULE_INFO();

	if (libxmp_init_instrument(m) < 0) {
		goto err3;
	}

	for (i = 0; i < mod->ins; i++) {
		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			goto err3;

		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].rls = 0xfff;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		libxmp_instrument_name(mod, i, mh.ins[i].name, 22);

		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d",
			     i, mod->xxi[i].name, mod->xxs[i].len,
			     mod->xxs[i].lps, mod->xxs[i].lpe,
			     mh.ins[i].loop_size > 1 ? 'L' : ' ',
			     mod->xxi[i].sub[0].vol,
			     mod->xxi[i].sub[0].fin >> 4);
	}

	if (libxmp_init_pattern(mod) < 0) {
		goto err3;
	}

	/* Load and convert patterns */
	D_(D_INFO "Stored patterns: %d", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			goto err3;

		for (j = 0; j < (64 * 4); j++) {
			event = &EVENT(i, j % 4, j / 4);
			hio_read(mod_event, 1, 4, f);
			libxmp_decode_protracker_event(event, mod_event);
		}
	}

	m->period_type = PERIOD_MODRNG;

	/* Load samples */

	D_(D_INFO "Stored samples: %d", mod->smp);
	for (i = 0; i < mod->smp; i++) {
		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
			goto err3;
	}

	hio_close(f);
	unlink_temp_file(temp_name);
	return 0;

    err3:
	hio_close(f);
    err2:
	unlink_temp_file(temp_name);
    err:
	return -1;
}
Exemple #10
0
static int ptdt_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	int i, j;
	struct xmp_event *event;
	struct mod_header mh;
	uint8 mod_event[4];

	hio_read(&mh.name, 20, 1, f);
	for (i = 0; i < 31; i++) {
		hio_read(&mh.ins[i].name, 22, 1, f);
		mh.ins[i].size = hio_read16b(f);
		mh.ins[i].finetune = hio_read8(f);
		mh.ins[i].volume = hio_read8(f);
		mh.ins[i].loop_start = hio_read16b(f);
		mh.ins[i].loop_size = hio_read16b(f);
	}
	mh.len = hio_read8(f);
	mh.restart = hio_read8(f);
	hio_read(&mh.order, 128, 1, f);
	hio_read(&mh.magic, 4, 1, f);

	mod->ins = 31;
	mod->smp = mod->ins;
	mod->chn = 4;
	mod->len = mh.len;
	mod->rst = mh.restart;
	memcpy(mod->xxo, mh.order, 128);

	for (i = 0; i < 128; i++) {
		if (mod->xxo[i] > mod->pat)
			mod->pat = mod->xxo[i];
	}

	mod->pat++;
	mod->trk = mod->chn * mod->pat;

	if (libxmp_init_instrument(m) < 0)
		return -1;

	for (i = 0; i < mod->ins; i++) {
		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		mod->xxs[i].len = 2 * mh.ins[i].size;
		mod->xxs[i].lps = 2 * mh.ins[i].loop_start;
		mod->xxs[i].lpe = mod->xxs[i].lps + 2 * mh.ins[i].loop_size;
		mod->xxs[i].flg = mh.ins[i].loop_size > 1 ? XMP_SAMPLE_LOOP : 0;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		mod->xxi[i].sub[0].fin = (int8)(mh.ins[i].finetune << 4);
		mod->xxi[i].sub[0].vol = mh.ins[i].volume;
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;
		mod->xxi[i].rls = 0xfff;

		libxmp_instrument_name(mod, i, mh.ins[i].name, 22);

		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %+d",
				i, mod->xxi[i].name,
				mod->xxs[i].len, mod->xxs[i].lps,
				mod->xxs[i].lpe,
				mh.ins[i].loop_size > 1 ? 'L' : ' ',
				mod->xxi[i].sub[0].vol,
				mod->xxi[i].sub[0].fin >> 4);
	}

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	/* Load and convert patterns */
	D_(D_INFO "Stored patterns: %d", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < (64 * 4); j++) {
			event = &EVENT(i, j % 4, j / 4);
			hio_read(mod_event, 1, 4, f);
			libxmp_decode_protracker_event(event, mod_event);
		}
	}

	m->period_type = PERIOD_MODRNG;

	/* Load samples */
	D_(D_INFO "Stored samples: %d", mod->smp);

	for (i = 0; i < mod->smp; i++) {
		if (!mod->xxs[i].len)
			continue;

		if (libxmp_load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	return 0;
}
Exemple #11
0
static int no_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j, k;
	int nsize;

	LOAD_INIT();

	hio_read32b(f);			/* NO 0x00 0x00 */

	libxmp_set_type(m, "Liquid Tracker");

	nsize = hio_read8(f);
	for (i = 0; i < nsize; i++) {
		uint8 x = hio_read8(f);
		if (i < XMP_NAME_SIZE)
			mod->name[i] = x;
	}

	hio_read16l(f);
	hio_read16l(f);
	hio_read16l(f);
	hio_read16l(f);
	hio_read8(f);
	mod->pat = hio_read8(f);
	hio_read8(f);
	mod->chn = hio_read8(f);
	mod->trk = mod->pat * mod->chn;
	hio_read8(f);
	hio_read16l(f);
	hio_read16l(f);
	hio_read8(f);
	mod->ins = mod->smp = 63;

	for (i = 0; i < 256; i++) {
		uint8 x = hio_read8(f);
		if (x == 0xff)
			break;
		mod->xxo[i] = x;
	}
	hio_seek(f, 255 - i, SEEK_CUR);
	mod->len = i;

	m->c4rate = C4_NTSC_RATE;

	MODULE_INFO();

	if (libxmp_init_instrument(m) < 0)
		return -1;

	/* Read instrument names */
	for (i = 0; i < mod->ins; i++) {
		int hasname, c2spd;

		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		nsize = hio_read8(f);
		if (hio_error(f)) {
			return -1;
		}

		hasname = 0;
		for (j = 0; j < nsize; j++) {
			uint8 x = hio_read8(f);
			if (x != 0x20)
				hasname = 1;
			if (j < 32)
				mod->xxi[i].name[j] = x;
		}
		if (!hasname)
			mod->xxi[i].name[0] = 0;

		hio_read32l(f);
		hio_read32l(f);
		mod->xxi[i].sub[0].vol = hio_read8(f);
		c2spd = hio_read16l(f);
		mod->xxs[i].len = hio_read16l(f);
		mod->xxs[i].lps = hio_read16l(f);
		mod->xxs[i].lpe = hio_read16l(f);
		hio_read32l(f);
		hio_read16l(f);

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		/*
		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;
		mod->xxi[i].sub[0].sid = i;

		D_(D_INFO "[%2X] %-22.22s  %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, c2spd);

		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
	}

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	/* Read and convert patterns */
	D_(D_INFO "Stored patterns: %d ", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < mod->xxp[i]->rows; j++) {
			for (k = 0; k < mod->chn; k++) {
				uint32 x, note, ins, vol, fxt, fxp;

				event = &EVENT (i, k, j);

				x = hio_read32l(f);
				note = x & 0x0000003f;
				ins = (x & 0x00001fc0) >> 6;
				vol = (x & 0x000fe000) >> 13;
				fxt = (x & 0x00f00000) >> 20;
				fxp = (x & 0xff000000) >> 24;

				if (note != 0x3f)
					event->note = 36 + note;
				if (ins != 0x7f)
					event->ins = 1 + ins;
				if (vol != 0x7f)
					event->vol = vol;
				if (fxt != 0x0f) {
					event->fxt = fx[fxt];
					event->fxp = fxp;
				}
			}
		}
	}

	/* Read samples */
	D_(D_INFO "Stored samples: %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		if (mod->xxs[i].len == 0)
			continue;
		if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	m->quirk |= QUIRKS_ST3;
	m->read_event_type = READ_EVENT_ST3;

	return 0;
}
Exemple #12
0
static int alm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int i, j;
    struct alm_file_header afh;
    struct xmp_event *event;
    struct stat stat;
    uint8 b;
    char *basename;
    char filename[NAME_SIZE];
    char modulename[NAME_SIZE];

    LOAD_INIT();

    hio_read(&afh.id, 7, 1, f);

    if (!strncmp((char *)afh.id, "ALEYMOD", 7))		/* Version 1.0 */
	mod->spd = afh.speed / 2;

    strncpy(modulename, m->filename, NAME_SIZE);
    basename = strtok (modulename, ".");

    afh.speed = hio_read8(f);
    afh.length = hio_read8(f);
    afh.restart = hio_read8(f);
    hio_read(&afh.order, 128, 1, f);

    mod->len = afh.length;
    mod->rst = afh.restart;
    memcpy (mod->xxo, afh.order, mod->len);

    for (mod->pat = i = 0; i < mod->len; i++)
	if (mod->pat < afh.order[i])
	    mod->pat = afh.order[i];
    mod->pat++;

    mod->ins = 31;
    mod->trk = mod->pat * mod->chn;
    mod->smp = mod->ins;
    m->c4rate = C4_NTSC_RATE;

    libxmp_set_type(m, "Aley's Module");

    MODULE_INFO();

    if (libxmp_init_pattern(mod) < 0)
	return -1;

    /* Read and convert patterns */
    D_(D_INFO "Stored patterns: %d", mod->pat);

    for (i = 0; i < mod->pat; i++) {
	if (libxmp_alloc_pattern_tracks(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);
	    if (b)
		event->note = (b == 37) ? 0x61 : b + 48;
	    event->ins = hio_read8(f);
	}
    }

    if (libxmp_init_instrument(m) < 0)
	return -1;

    /* Read and convert instruments and samples */

    D_(D_INFO "Loading samples: %d", mod->ins);

    for (i = 0; i < mod->ins; i++) {
	HIO_HANDLE *s;

	if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
	    return -1;

	mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1);
	snprintf(filename, NAME_SIZE, "%s.%d", basename, i + 1);
	s = hio_open_file(filename, "rb");

	if (s == NULL)
	    continue;

	mod->xxi[i].nsm = 1;

	hio_stat(s, &stat);
	b = hio_read8(s);		/* Get first octet */
	mod->xxs[i].len = stat.st_size - 5 * !b;

	if (!b) {		/* Instrument with header */
	    mod->xxs[i].lps = hio_read16l(f);
	    mod->xxs[i].lpe = hio_read16l(f);
	    mod->xxs[i].flg = mod->xxs[i].lpe > mod->xxs[i].lps ? XMP_SAMPLE_LOOP : 0;
	} else {
	    hio_seek(s, 0, SEEK_SET);
	}

	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].vol = 0x40;
	mod->xxi[i].sub[0].sid = i;

	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x", i,
		filename, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ', mod->xxi[i].sub[0].vol);

	if (libxmp_load_sample(m, s, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
	    return -1;

	hio_close(s);
    }

    /* ALM is LRLR, not LRRL */
    for (i = 0; i < mod->chn; i++)
	mod->xxc[i].pan = DEFPAN((i % 2) * 0xff);

    return 0;
}
Exemple #13
0
static int tcb_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j, k;
	uint8 buffer[10];
	int base_offs, soffs[16];
	uint8 unk1[16], unk2[16], unk3[16];

	LOAD_INIT();

	hio_read(buffer, 8, 1, f);

	libxmp_set_type(m, "TCB Tracker", buffer);

	hio_read16b(f);	/* ? */
	mod->pat = hio_read16b(f);
	mod->ins = 16;
	mod->smp = mod->ins;
	mod->chn = 4;
	mod->trk = mod->pat * mod->chn;

	m->quirk |= QUIRK_MODRNG;

	hio_read16b(f);	/* ? */

	for (i = 0; i < 128; i++)
		mod->xxo[i] = hio_read8(f);

	mod->len = hio_read8(f);
	hio_read8(f);	/* ? */
	hio_read16b(f);	/* ? */

	MODULE_INFO();

	if (libxmp_init_instrument(m) < 0)
		return -1;

	/* Read instrument names */
	for (i = 0; i < mod->ins; i++) {
		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;
		hio_read(buffer, 8, 1, f);
		libxmp_instrument_name(mod, i, buffer, 8);
	}

	hio_read16b(f);	/* ? */
	for (i = 0; i < 5; i++)
		hio_read16b(f);
	for (i = 0; i < 5; i++)
		hio_read16b(f);
	for (i = 0; i < 5; i++)
		hio_read16b(f);

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	/* Read and convert patterns */
	D_(D_INFO "Stored patterns: %d ", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < mod->xxp[i]->rows; j++) {
			for (k = 0; k < mod->chn; k++) {
				int b;
				event = &EVENT (i, k, j);

				b = hio_read8(f);
				if (b) {
					event->note = 12 * (b >> 4);
					event->note += (b & 0xf) + 36;
				}
				b = hio_read8(f);
				event->ins = b >> 4;
				if (event->ins)
					event->ins += 1;
				if (b &= 0x0f) {
					switch (b) {
					case 0xd:
						event->fxt = FX_BREAK;
						event->fxp = 0;
						break;
					default:
						printf("---> %02x\n", b);
					}
				}
			}
		}
	}

	base_offs = hio_tell(f);
	hio_read32b(f);	/* remaining size */

	/* Read instrument data */

	for (i = 0; i < mod->ins; i++) {
		mod->xxi[i].sub[0].vol = hio_read8(f) / 2;
		mod->xxi[i].sub[0].pan = 0x80;
		unk1[i] = hio_read8(f);
		unk2[i] = hio_read8(f);
		unk3[i] = hio_read8(f);
	}


	for (i = 0; i < mod->ins; i++) {
		soffs[i] = hio_read32b(f);
		mod->xxs[i].len = hio_read32b(f);
	}

	hio_read32b(f);
	hio_read32b(f);
	hio_read32b(f);
	hio_read32b(f);

	for (i = 0; i < mod->ins; i++) {
		mod->xxi[i].nsm = !!(mod->xxs[i].len);
		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;
		mod->xxi[i].sub[0].sid = i;

		D_(D_INFO "[%2X] %-8.8s  %04x %04x %04x %c "
						"V%02x  %02x %02x %02x\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, unk1[i], unk2[i], unk3[i]);
	}

	/* Read samples */

	D_(D_INFO "Stored samples: %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		hio_seek(f, start + base_offs + soffs[i], SEEK_SET);
		if (libxmp_load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	return 0;
}