Example #1
0
static void get_info(struct module_data *m, int size, FILE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	int flags;
	int day, month, year, hour, min, sec;
	int dhour, dmin, dsec;

	fread(mod->name, 1, 32, f);
	mod->ins = read16b(f);
	mod->len = read16b(f);
	mod->pat = read16b(f);
	mod->gvl = read16b(f);
	mod->bpm = read16b(f);
	flags = read16b(f);
	day   = read16b(f);
	month = read16b(f);
	year  = read16b(f);
	hour  = read16b(f);
	min   = read16b(f);
	sec   = read16b(f);
	dhour = read16b(f);
	dmin  = read16b(f);
	dsec  = read16b(f);

	MODULE_INFO();

	D_(D_INFO "Creation date: %02d/%02d/%02d %02d:%02d:%02d",
		       day, month, year, hour, min, sec);
	D_(D_INFO "Playing time: %02d:%02d:%02d", dhour, dmin, dsec);
}
Example #2
0
static int get_info(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	int flags;
	/* int day, month, year, hour, min, sec;
	int dhour, dmin, dsec; */

	hio_read(mod->name, 1, 32, f);
	mod->ins = hio_read16b(f);
	mod->len = hio_read16b(f);
	mod->pat = hio_read16b(f);
	mod->gvl = hio_read16b(f);
	mod->bpm = hio_read16b(f);
	flags = hio_read16b(f);
	/*day   =*/ hio_read16b(f);
	/*month =*/ hio_read16b(f);
	/*year  =*/ hio_read16b(f);
	/*hour  =*/ hio_read16b(f);
	/*min   =*/ hio_read16b(f);
	/*sec   =*/ hio_read16b(f);
	/*dhour =*/ hio_read16b(f);
	/*dmin  =*/ hio_read16b(f);
	/*dsec  =*/ hio_read16b(f);

	MODULE_INFO();

	/*D_(D_INFO "Creation date: %02d/%02d/%02d %02d:%02d:%02d",
		       day, month, year, hour, min, sec);
	D_(D_INFO "Playing time: %02d:%02d:%02d", dhour, dmin, dsec);*/

	return 0;
}
static int okt_load(struct xmp_context *ctx, FILE *f, const int start)
{
    struct xmp_player_context *p = &ctx->p;
    struct xmp_mod_context *m = &p->m;

    LOAD_INIT();

    fseek(f, 8, SEEK_CUR);	/* OKTASONG */

    pattern = sample = 0;

    /* IFF chunk IDs */
    iff_register("CMOD", get_cmod);
    iff_register("SAMP", get_samp);
    iff_register("SPEE", get_spee);
    iff_register("SLEN", get_slen);
    iff_register("PLEN", get_plen);
    iff_register("PATT", get_patt);
    iff_register("PBOD", get_pbod);
    iff_register("SBOD", get_sbod);

    strcpy (m->type, "OKT (Oktalyzer)");

    MODULE_INFO();

    /* Load IFF chunks */
    while (!feof(f))
	iff_chunk(ctx, f);

    iff_release();

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

    return 0;
}
Example #4
0
int ftm_load(xmp_file f)
{
	int i, j, k;
	struct xmp_event *event;
	struct ftm_header fh;
	struct ftm_instrument si;
	uint8 b1, b2, b3;

	LOAD_INIT();

	xmp_fread(&fh.id, 4, 1, f);
	if (memcmp(fh.id, "FTMN", 4))
		return -1;

	fh.ver = read8(f);
	fh.nos = read8(f);
	read16b(f);
	read32b(f);
	read32b(f);
	xmp_fread(&fh.title, 32, 1, f);
	xmp_fread(&fh.author, 32, 1, f);
	read16b(f);

	//mod->len = fh.len;
	//mod->pat = fh.pat;
	mod->ins = fh.nos;
	mod->smp = mod->ins;
	mod->trk = mod->pat * mod->chn;
	for (i = 0; i < mod->len; i++)
		mod->xxo[i] = fh.order[i];

	set_type(m, "Face The Music");
	MODULE_INFO();
	PATTERN_INIT();

	/* Load and convert patterns */
	if (V(0))
		report("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 < 4; j++) {
		}

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

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

	for (i = 0; i < mod->smp; i++) {
		reportv(ctx, 0, ".");
	}

	reportv(ctx, 0, "\n");
	mod->flg |= XXM_FLG_MODRNG;

	return 0;
}
static int mfp_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, k, x, y;
	struct xxm_event *event;
	struct stat st;
	char smp_filename[PATH_MAX];
	FILE *s;
	int size1, size2;
	int pat_addr, pat_table[128][4];
	uint8 buf[1024], mod_event[4];
	int row;

	LOAD_INIT();

	sprintf(m->type, "Magnetic Fields Packer");
	MODULE_INFO();

	m->xxh->chn = 4;

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

	reportv(ctx, 1, "     Len  LBeg LEnd L Vol Fin\n");

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

		m->xxi[i] = calloc(sizeof(struct xxm_instrument), 1);
		
		m->xxs[i].len = 2 * read16b(f);
		m->xxi[i][0].fin = (int8)(read8(f) << 4);
		m->xxi[i][0].vol = read8(f);
		m->xxs[i].lps = 2 * read16b(f);
		loop_size = read16b(f);

		m->xxs[i].lpe = m->xxs[i].lps + 2 * loop_size;
		m->xxs[i].flg = loop_size > 1 ? WAVE_LOOPING : 0;
		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;

		if (V(1) && m->xxs[i].len > 2) {
                	report("[%2X] %04x %04x %04x %c V%02x %+d %c\n",
                       		i, m->xxs[i].len, m->xxs[i].lps,
                        	m->xxs[i].lpe,
				loop_size > 1 ? 'L' : ' ',
                        	m->xxi[i][0].vol, m->xxi[i][0].fin >> 4,
                        	m->xxs[i].flg & WAVE_PTKLOOP ? '!' : ' ');
		}
	}
Example #6
0
//----------------------------------------------------------------------------
void CModuleParent::addChildModule(IModule* module)
{
    MODULE_INFO( "Module parent : simply adding a child module" );
    MODULE_AST( module );
#ifdef RY_MODULE_DEBUG
    NLMISC::CRefPtr<IModule> ref(module);
    std::vector< NLMISC::CRefPtr<IModule> >::iterator it( std::find( _Modules.begin(), _Modules.end(), ref ) );
    if ( it != _Modules.end() )
        nlerror("a module was added twice");
#endif
    _Modules.push_back(module);
}
Example #7
0
//----------------------------------------------------------------------------
CModuleParent::~CModuleParent()
{
    MODULE_INFO( "Module parent destruction : calling the Ondestruction handler for all modules" );
    // as module could be removed from thi parent in IModule::onParentDestruction, we have do remove modules with this strange way
    std::vector< NLMISC::CRefPtr<IModule> > modules = _Modules;
    for (uint i = 0; i < modules.size(); i++ )
    {
        if ( modules[i] )
        {
            modules[i]->onParentDestruction();
        }
    }
}
Example #8
0
//----------------------------------------------------------------------------
void CModuleParent::removeChildModule(IModule* module)
{
    MODULE_INFO( "Module parent : simply removing a child module" );
    MODULE_AST( module );
    MODULE_AST(_Owner);
    NLMISC::CRefPtr<IModule> ref(module);
    std::vector< NLMISC::CRefPtr<IModule> >::iterator it( std::find( _Modules.begin(), _Modules.end(), ref ) );
    if ( it == _Modules.end() )
    {
        nlwarning("<MODULE> cant find the module to remove");
        return;
    }
    _Modules.erase(it);
}
Example #9
0
static int dbm_load(struct module_data *m, FILE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	iff_handle handle;
	char name[44];
	uint16 version;
	int i;
	struct local_data data;

	LOAD_INIT();

	read32b(f);		/* DBM0 */

	data.have_song = 0;
	version = read16b(f);

	fseek(f, 10, SEEK_CUR);
	fread(name, 1, 44, f);

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

	/* IFF chunk IDs */
	iff_register(handle, "INFO", get_info);
	iff_register(handle, "SONG", get_song);
	iff_register(handle, "INST", get_inst);
	iff_register(handle, "PATT", get_patt);
	iff_register(handle, "SMPL", get_smpl);
	iff_register(handle, "VENV", get_venv);

	strncpy(mod->name, name, XMP_NAME_SIZE);
	snprintf(mod->type, XMP_NAME_SIZE, "DigiBooster Pro %d.%02x DBM0",
					version >> 8, version & 0xff);
	MODULE_INFO();

	/* Load IFF chunks */
	while (!feof(f)) {
		iff_chunk(handle, m, f, &data);
	}

	iff_release(handle);

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

	return 0;
}
static void get_emic(struct xmp_context *ctx, int size, FILE *f)
{
    struct xmp_player_context *p = &ctx->p;
    struct xmp_mod_context *m = &p->m;
    int i, ver;

    ver = read16b(f);
    fread(m->name, 1, 20, f);
    fread(m->author, 1, 20, f);
    m->xxh->bpm = read8(f);
    m->xxh->ins = read8(f);
    m->xxh->smp = m->xxh->ins;

    m->xxh->flg |= XXM_FLG_MODRNG;

    snprintf(m->type, XMP_NAMESIZE, "EMOD v%d (Quadra Composer)", ver);
    MODULE_INFO();

    INSTRUMENT_INIT();

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

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

	read8(f);		/* num */
	m->xxi[i][0].vol = read8(f);
	m->xxs[i].len = 2 * read16b(f);
	fread(m->xxih[i].name, 1, 20, f);
	m->xxs[i].flg = read8(f) & 1 ? WAVE_LOOPING : 0;
	m->xxi[i][0].fin = read8(f);
	m->xxs[i].lps = 2 * read16b(f);
	m->xxs[i].lpe = m->xxs[i].lps + 2 * read16b(f);
	read32b(f);		/* ptr */

	m->xxih[i].nsm = 1;
	m->xxi[i][0].pan = 0x80;
	m->xxi[i][0].sid = i;

	if (V(1) && (strlen((char *)m->xxih[i].name) || (m->xxs[i].len > 2))) {
	    report ("[%2X] %-20.20s %05x %05x %05x %c V%02x %+d\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, m->xxi[i][0].fin >> 4);
	}
    }
Example #11
0
static int okt_load(struct module_data *m, HIO_HANDLE * f, const int start)
{
    iff_handle handle;
    struct local_data data;
    int ret;

    LOAD_INIT();

    hio_seek(f, 8, SEEK_CUR);	/* OKTASONG */

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

    memset(&data, 0, sizeof(struct local_data));

    /* IFF chunk IDs */
    ret = iff_register(handle, "CMOD", get_cmod);
    ret |= iff_register(handle, "SAMP", get_samp);
    ret |= iff_register(handle, "SPEE", get_spee);
    ret |= iff_register(handle, "SLEN", get_slen);
    ret |= iff_register(handle, "PLEN", get_plen);
    ret |= iff_register(handle, "PATT", get_patt);
    ret |= iff_register(handle, "PBOD", get_pbod);
    ret |= iff_register(handle, "SBOD", get_sbod);

    if (ret != 0)
        return -1;

    set_type(m, "Oktalyzer");

    MODULE_INFO();

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

    iff_release(handle);

    return 0;
}
Example #12
0
static int dbm_load(struct xmp_context *ctx, FILE *f, const int start)
{
	struct xmp_player_context *p = &ctx->p;
	struct xmp_mod_context *m = &p->m;
	char name[44];
	uint16 version;
	int i;

	LOAD_INIT();

	read32b(f);		/* DBM0 */

	have_song = 0;
	version = read16b(f);

	fseek(f, 10, SEEK_CUR);
	fread(name, 1, 44, f);

	/* IFF chunk IDs */
	iff_register("INFO", get_info);
	iff_register("SONG", get_song);
	iff_register("INST", get_inst);
	iff_register("PATT", get_patt);
	iff_register("SMPL", get_smpl);
	iff_register("VENV", get_venv);

	strncpy(m->name, name, XMP_NAMESIZE);
	snprintf(m->type, XMP_NAMESIZE, "DBM0 (DigiBooster Pro "
				"%d.%02x)", version >> 8, version & 0xff);
	MODULE_INFO();

	/* Load IFF chunks */
	while (!feof(f))
		iff_chunk(ctx, f);

	iff_release();

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

	return 0;
}
Example #13
0
static int get_d_t_(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	int b;

	hio_read16b(f);			/* type */
	hio_read16b(f);			/* 0xff then mono */
	hio_read16b(f);			/* reserved */
	mod->spd = hio_read16b(f);
	if ((b = hio_read16b(f)) > 0)	/* RAMBO.DTM has bpm 0 */
		mod->bpm = b;
	hio_read32b(f);			/* undocumented */

	hio_read(mod->name, 32, 1, f);
	set_type(m, "Digital Tracker DTM");

	MODULE_INFO();

	return 0;
}
Example #14
0
static int okt_load(struct module_data *m, xmp_file f, const int start)
{
    iff_handle handle;
    struct local_data data;

    LOAD_INIT();

    xmp_fseek(f, 8, SEEK_CUR);	/* OKTASONG */

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

    memset(&data, 0, sizeof(struct local_data));

    /* IFF chunk IDs */
    iff_register(handle, "CMOD", get_cmod);
    iff_register(handle, "SAMP", get_samp);
    iff_register(handle, "SPEE", get_spee);
    iff_register(handle, "SLEN", get_slen);
    iff_register(handle, "PLEN", get_plen);
    iff_register(handle, "PATT", get_patt);
    iff_register(handle, "PBOD", get_pbod);
    iff_register(handle, "SBOD", get_sbod);

    set_type(m, "Oktalyzer");

    MODULE_INFO();

    /* Load IFF chunks */
    while (!xmp_feof(f)) {
	iff_chunk(handle, m, f, &data);
    }

    iff_release(handle);

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

	LOAD_INIT();

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

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

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

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

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

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

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

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

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

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

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

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

	/* Read and convert patterns */

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

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

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

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

	pat_addr = hio_tell(f);

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

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

			hio_read(buf, 1, 1024, f);

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

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

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

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

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

	hio_close(s);

	m->quirk |= QUIRK_MODRNG;

	return 0;

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

	return 0;
}
Example #16
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;
}
Example #17
0
static int get_emic(struct module_data *m, int size, HIO_HANDLE * f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	int i, ver;
	uint8 reorder[256];

	ver = hio_read16b(f);
	hio_read(mod->name, 1, 20, f);
	hio_seek(f, 20, SEEK_CUR);
	mod->bpm = hio_read8(f);
	mod->ins = hio_read8(f);
	mod->smp = mod->ins;

	m->quirk |= QUIRK_MODRNG;

	snprintf(mod->type, XMP_NAME_SIZE, "Quadra Composer EMOD v%d", ver);
	MODULE_INFO();

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

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

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

		sub = &xxi->sub[0];

		hio_read8(f);	/* num */
		sub->vol = hio_read8(f);
		xxs->len = 2 * hio_read16b(f);
		hio_read(xxi->name, 1, 20, f);
		xxs->flg = hio_read8(f) & 1 ? XMP_SAMPLE_LOOP : 0;
		sub->fin = hio_read8s(f) << 4;
		xxs->lps = 2 * hio_read16b(f);
		xxs->lpe = xxs->lps + 2 * hio_read16b(f);
		hio_read32b(f);	/* ptr */

		xxi->nsm = 1;
		sub->pan = 0x80;
		sub->sid = i;

		D_(D_INFO "[%2X] %-20.20s %05x %05x %05x %c V%02x %+d",
			i, xxi->name, xxs->len, xxs->lps, xxs->lpe,
			xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
			sub->vol, sub->fin >> 4);
	}

	hio_read8(f);		/* pad */
	mod->pat = hio_read8(f);
	mod->trk = mod->pat * mod->chn;

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

	memset(reorder, 0, 256);

	for (i = 0; i < mod->pat; i++) {
		reorder[hio_read8(f)] = i;

		if (pattern_tracks_alloc(mod, i, hio_read8(f) + 1) < 0)
			return -1;

		hio_seek(f, 20, SEEK_CUR);	/* skip name */
		hio_read32b(f);	/* ptr */
	}

	mod->len = hio_read8(f);

	D_(D_INFO "Module length: %d", mod->len);

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

	return 0;
}
Example #18
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;
}
Example #19
0
static int asylum_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j;

	LOAD_INIT();

	hio_seek(f, 32, SEEK_CUR);			/* skip magic */
	mod->spd = hio_read8(f);			/* initial speed */
	mod->bpm = hio_read8(f);			/* initial BPM */
	mod->ins = hio_read8(f);			/* number of instruments */
	mod->pat = hio_read8(f);			/* number of patterns */
	mod->len = hio_read8(f);			/* module length */
	hio_read8(f);

	hio_read(mod->xxo, 1, mod->len, f);	/* read orders */
	hio_seek(f, start + 294, SEEK_SET);

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

	snprintf(mod->type, XMP_NAME_SIZE, "Asylum Music Format v1.0");

	MODULE_INFO();

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

	/* Read and convert instruments and samples */
	for (i = 0; i < mod->ins; i++) {
		uint8 insbuf[37];

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

		hio_read(insbuf, 1, 37, f);
		instrument_name(mod, i, insbuf, 22);
		mod->xxi[i].sub[0].fin = (int8)(insbuf[22] << 4);
		mod->xxi[i].sub[0].vol = insbuf[23];
		mod->xxi[i].sub[0].xpo = (int8)insbuf[24];
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;

		mod->xxs[i].len = readmem32l(insbuf + 25);
		mod->xxs[i].lps = readmem32l(insbuf + 29);
		mod->xxs[i].lpe = mod->xxs[i].lps + readmem32l(insbuf + 33);
		
		mod->xxs[i].flg = mod->xxs[i].lpe > 2 ? XMP_SAMPLE_LOOP : 0;

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

	hio_seek(f, 37 * (64 - mod->ins), SEEK_CUR);

	D_(D_INFO "Module length: %d", mod->len);

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

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

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

		for (j = 0; j < 64 * mod->chn; j++) {
			uint8 note;

			event = &EVENT(i, j % mod->chn, j / mod->chn);
			memset(event, 0, sizeof(struct xmp_event));
			note = hio_read8(f);

			if (note != 0) {
				event->note = note + 13;
			}

			event->ins = hio_read8(f);
			event->fxt = hio_read8(f);
			event->fxp = hio_read8(f);
		}
	}

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

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

	return 0;
}
Example #20
0
static int mod_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];
    char magic[8];
    int ptkloop = 0;			/* Protracker loop */

    LOAD_INIT();

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

    m->quirk |= QUIRK_MODRNG;

    hio_read(&mh.name, 20, 1, f);
    for (i = 0; i < 31; i++) {
	hio_read(&mh.ins[i].name, 22, 1, f);	/* Instrument name */
	mh.ins[i].size = hio_read16b(f);	/* Length in 16-bit words */
	mh.ins[i].finetune = hio_read8(f);	/* Finetune (signed nibble) */
	mh.ins[i].volume = hio_read8(f);	/* Linear playback volume */
	mh.ins[i].loop_start = hio_read16b(f);	/* Loop start in 16-bit words */
	mh.ins[i].loop_size = hio_read16b(f);	/* Loop size in 16-bit words */
    }
    mh.len = hio_read8(f);
    mh.restart = hio_read8(f);
    hio_read(&mh.order, 128, 1, f);
    memset(magic, 0, 8);
    hio_read(magic, 4, 1, f);

    if (!memcmp(magic, "M.K.", 4)) {
	mod->chn = 4;
    } else if (!strncmp(magic + 2, "CH", 2) &&
	isdigit((int)magic[0]) && isdigit((int)magic[1])) {
	mod->chn = (*magic - '0') * 10 + magic[1] - '0';
    } else if (!strncmp(magic + 1, "CHN", 3) && isdigit((int)*magic)) {
	mod->chn = *magic - '0';
    } else {
	return -1;
    }

    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++;

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

    for (i = 0; i < mod->ins; i++) {
	if (subinstrument_alloc(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;
	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 >= 4) ?
		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;
	instrument_name(mod, i, mh.ins[i].name, 22);

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

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

    set_type(m, mod->chn == 4 ? "Protracker" : "Fasttracker");

    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 ? '!' : ' ');
    }

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

    /* Load 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);
	    hio_read (mod_event, 1, 4, f);
	    decode_protracker_event(event, mod_event);
	}
    }

    /* Load samples */

    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 (load_sample(m, f, flags, &mod->xxs[i], NULL) < 0)
	    return -1;
    }

    if (mod->chn > 4) {
	m->quirk &= ~QUIRK_MODRNG;
	m->quirk |= QUIRKS_FT2;
	m->read_event_type = READ_EVENT_FT2;
    }

    return 0;
}
Example #21
0
static int polly_load(struct module_data *m, FILE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	uint8 *buf;
	int i, j, k;

	LOAD_INIT();

	read8(f);			/* skip 0xae */
	/*
	 * File is RLE-encoded, escape is 0xAE (Aleksi Eeben's initials).
	 * Actual 0xAE is encoded as 0xAE 0x01
	 */
	if ((buf = calloc(1, 0x10000)) == NULL)
		return -1;

	decode_rle(buf, f, 0x10000);

	for (i = 0; buf[ORD_OFS + i] != 0 && i < 128; i++)
		mod->xxo[i] = buf[ORD_OFS + i] - 0xe0;
	mod->len = i;

	memcpy(mod->name, buf + ORD_OFS + 160, 16);
	/* memcpy(m->author, buf + ORD_OFS + 176, 16); */
	set_type(m, "Polly Tracker");
	MODULE_INFO();

	mod->spd = 0x03;
	mod->bpm = 0x7d * buf[ORD_OFS + 193] / 0x88;
#if 0
	for (i = 0; i < 1024; i++) {
		if ((i % 16) == 0) printf("\n");
		printf("%02x ", buf[ORD_OFS + i]);
	}
#endif

	mod->pat = 0;
	for (i = 0; i < mod->len; i++) {
		if (mod->xxo[i] > mod->pat)
			mod->pat = mod->xxo[i];
	}
	mod->pat++;
	
	mod->chn = 4;
	mod->trk = mod->pat * mod->chn;

	PATTERN_INIT();

	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; j++) {
			for (k = 0; k < 4; k++) {
				uint8 x = buf[i * PAT_SIZE + j * 4 + k];
				event = &EVENT(i, k, j);
				if (x == 0xf0) {
					event->fxt = FX_BREAK;
					event->fxp = 0;
					continue;
				}
				event->note = LSN(x);
				if (event->note)
					event->note += 48;
				event->ins = MSN(x);
			}
		}
	}

	mod->ins = mod->smp = 15;
	INSTRUMENT_INIT();

	for (i = 0; i < 15; i++) {
		mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 1);
		mod->xxs[i].len = buf[ORD_OFS + 129 + i] < 0x10 ? 0 :
					256 * buf[ORD_OFS + 145 + i];
		mod->xxi[i].sub[0].fin = 0;
		mod->xxi[i].sub[0].vol = 0x40;
		mod->xxs[i].lps = 0;
		mod->xxs[i].lpe = 0;
		mod->xxs[i].flg = 0;
		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;

                D_(D_INFO "[%2X] %04x %04x %04x %c V%02x",
                       		i, mod->xxs[i].len, mod->xxs[i].lps,
                        	mod->xxs[i].lpe, ' ', mod->xxi[i].sub[0].vol);
	}

	/* Convert samples from 6 to 8 bits */
	for (i = SMP_OFS; i < 0x10000; i++)
		buf[i] = buf[i] << 2;

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

	for (i = 0; i < mod->ins; i++) {
		if (mod->xxs[i].len == 0)
			continue;
		load_sample(NULL, SAMPLE_FLAG_NOLOAD | SAMPLE_FLAG_UNS,
				&mod->xxs[mod->xxi[i].sub[0].sid],
				(char*)buf + ORD_OFS + 256 +
					256 * (buf[ORD_OFS + 129 + i] - 0x10));
	}

	free(buf);

	/* make it mono */
	for (i = 0; i < mod->chn; i++)
		mod->xxc[i].pan = 0x80;

	m->quirk |= QUIRK_MODRNG;

	return 0;
}
Example #22
0
static int hsc_load(struct module_data *m, xmp_file 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();

    xmp_fread(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;

    xmp_fseek(f, start + 0, SEEK_SET);

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

    m->quirk |= QUIRK_LINEAR;

    set_type(m, "HSC-Tracker");

    MODULE_INFO();

    /* Read instruments */
    INSTRUMENT_INIT();

    xmp_fread (buf, 1, 128 * 12, f);
    sid = buf;
    for (i = 0; i < mod->ins; i++, sid += 12) {
	mod->xxi[i].sub = calloc(sizeof (struct xmp_subinstrument), 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 */

	load_sample(m, f, SAMPLE_FLAG_ADLIB | SAMPLE_FLAG_HSC,
					&mod->xxs[i], (char *)sid);
    }

    /* Read orders */
    for (pat = i = 0; i < 51; i++) {
	xmp_fread (&mod->xxo[i], 1, 1, f);
	if (mod->xxo[i] & 0x80)
	    break;			/* FIXME: jump line */
	if (mod->xxo[i] > pat)
	    pat = mod->xxo[i];
    }
    xmp_fseek(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);

    PATTERN_INIT();

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

	PATTERN_ALLOC (i);
	mod->xxp[i]->rows = 64;
	TRACK_ALLOC (i);
        for (r = 0; r < mod->xxp[i]->rows; r++) {
            for (c = 0; c < 9; c++) {
	        xmp_fread (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;
}
Example #23
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;
}
Example #24
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;
		}
	}
Example #25
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;
}
Example #26
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);
	}
Example #27
0
static int gtk_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[40];
	int rows, bits, c2spd, size;
	int ver, patmax;

	LOAD_INIT();

	hio_read(buffer, 4, 1, f);
	ver = buffer[3];
	hio_read(mod->name, 32, 1, f);
	set_type(m, "Graoumf Tracker GTK v%d", ver);
	hio_seek(f, 160, SEEK_CUR);	/* skip comments */

	mod->ins = hio_read16b(f);
	mod->smp = mod->ins;
	rows = hio_read16b(f);
	mod->chn = hio_read16b(f);
	mod->len = hio_read16b(f);
	mod->rst = hio_read16b(f);
	m->volbase = 0x100;

	MODULE_INFO();

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

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

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

		hio_read(buffer, 28, 1, f);
		instrument_name(mod, i, buffer, 28);

		if (ver == 1) {
			hio_read32b(f);
			mod->xxs[i].len = hio_read32b(f);
			mod->xxs[i].lps = hio_read32b(f);
			size = hio_read32b(f);
			mod->xxs[i].lpe = mod->xxs[i].lps + size - 1;
			hio_read16b(f);
			hio_read16b(f);
			mod->xxi[i].sub[0].vol = 0xff;
			mod->xxi[i].sub[0].pan = 0x80;
			bits = 1;
			c2spd = 8363;
		} else {
			hio_seek(f, 14, SEEK_CUR);
			hio_read16b(f);		/* autobal */
			bits = hio_read16b(f);	/* 1 = 8 bits, 2 = 16 bits */
			c2spd = hio_read16b(f);
			c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
			mod->xxs[i].len = hio_read32b(f);
			mod->xxs[i].lps = hio_read32b(f);
			size = hio_read32b(f);
			mod->xxs[i].lpe = mod->xxs[i].lps + size - 1;
			mod->xxi[i].sub[0].vol = hio_read16b(f);
			hio_read8(f);
			mod->xxi[i].sub[0].fin = hio_read8s(f);
		}

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

		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);
	}
Example #28
0
static int hmn_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;
	struct mupp mupp[31];
	uint8 mod_event[4];
	int mupp_index, num_mupp;

	LOAD_INIT();

	/*
	 *    clr.b   $1c(a6) ;prog on/off
	 *    CMP.L   #'Mupp',-$16(a3,d4.l)
	 *    bne.s   noprgo
	 *    move.l  a0,-(a7)
	 *    move.b  #1,$1c(a6)      ;prog on
	 *    move.l  l697,a0
	 *    lea     $43c(a0),a0
	 *    moveq   #0,d2
	 *    move.b  -$16+$4(a3,d4.l),d2     ;pattno
	 *    mulu    #$400,d2
	 *    lea     (a0,d2.l),a0
	 *    move.l  a0,4(a6)        ;proginstr data-start
	 *    moveq   #0,d2
	 *    MOVE.B  $3C0(A0),$12(A6)
	 *    AND.B   #$7F,$12(A6)
	 *    move.b  $380(a0),d2
	 *    mulu    #$20,d2
	 *    lea     (a0,d2.w),a0
	 *    move.l  a0,$a(a6)       ;loopstartmempoi = startmempoi
	 *    move.B  $3(a3,d4.l),$13(a6)     ;volume
	 *    move.b  -$16+$5(a3,d4.l),8(a6)  ;dataloopstart
	 *    move.b  -$16+$6(a3,d4.l),9(a6)  ;dataloopend
	 *    move.w  #$10,$e(a6)     ;looplen
	 *    move.l  (a7)+,a0
	 *    MOVE.W  $12(A6),(A2)
	 *    AND.W   #$FF,(A2)
	 *    BRA.S   L505_LQ
	 */

	/*
	 * Wavetable structure is 22 * 32 byte waveforms and 32 byte
	 * wave control data with looping.
	 */
	memset(mupp, 0, 31 * sizeof (struct mupp));

	hio_read(&mh.name, 20, 1, f);
	num_mupp = 0;

	for (i = 0; i < 31; i++) {
		hio_read(&mh.ins[i].name, 22, 1, f);	/* Instrument name */
		if (memcmp(mh.ins[i].name, "Mupp", 4) == 0) {
			mupp[i].prgon = 1;
			mupp[i].pattno = mh.ins[i].name[4];
			mupp[i].dataloopstart = mh.ins[i].name[5];
			mupp[i].dataloopend = mh.ins[i].name[6];
			num_mupp++;
		}

		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->chn = 4;
	mod->ins = 31;
	mod->smp = mod->ins + 28 * num_mupp;
	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 (hmn_new_module_extras(m) != 0)
		return -1;

	strncpy(mod->name, (char *)mh.name, 20);
	set_type(m, "%s (%4.4s)", "His Master's Noise", mh.magic);
	MODULE_INFO();

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

	for (i = 0; i < mod->ins; i++) {
		if (mupp[i].prgon) {
			mod->xxi[i].nsm = 28;
			snprintf(mod->xxi[i].name, 32,
				"Mupp %02x %02x %02x", mupp[i].pattno,
				mupp[i].dataloopstart, mupp[i].dataloopend);
			if (hmn_new_instrument_extras(&mod->xxi[i]) != 0)
				return -1;
		} else {
			mod->xxi[i].nsm = 1;
			instrument_name(mod, i, mh.ins[i].name, 22);

			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 (subinstrument_alloc(mod, i, mod->xxi[i].nsm) < 0)
			return -1;

		for (j = 0; j < mod->xxi[i].nsm; j++) {
			mod->xxi[i].sub[j].fin =
					-(int8)(mh.ins[i].finetune << 3);
			mod->xxi[i].sub[j].vol = mh.ins[i].volume;
			mod->xxi[i].sub[j].pan = 0x80;
			mod->xxi[i].sub[j].sid = i;
		}
	}

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

	/* Load 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 * 4); j++) {
			event = &EVENT(i, j % 4, j / 4);
			hio_read(mod_event, 1, 4, f);
			decode_protracker_event(event, mod_event);

			switch (event->fxt) {
			case 0x07:
				event->fxt = FX_MEGAARP;
				break;
			case 0x08:
			case 0x09:
			case 0x0e:
				event->fxt = event->fxp = 0;
				break;
			}
		}
	}

	m->quirk |= QUIRK_MODRNG;

	/* Load samples */

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

	for (i = 0; i < 31; i++) {
		if (load_sample(m, f, SAMPLE_FLAG_FULLREP,
						&mod->xxs[i], NULL) < 0) {
			return -1;
		}
	}


	/* Load Mupp samples */

	mupp_index = 0;
	for (i = 0; i < 31; i ++) {
		struct hmn_instrument_extras *extra =
			(struct hmn_instrument_extras *)mod->xxi[i].extra;

		if (!mupp[i].prgon)
			continue;

		hio_seek(f, start + 1084 + 1024 * mupp[i].pattno, SEEK_SET);
		for (j = 0; j < 28; j++) {
			int k = 31 + 28 * mupp_index + j;
			mod->xxi[i].sub[j].sid = k;
			mod->xxs[k].len = 32;
			mod->xxs[k].lps = 0;
			mod->xxs[k].lpe = 32;
			mod->xxs[k].flg = XMP_SAMPLE_LOOP;
			if (load_sample(m, f, 0, &mod->xxs[k], NULL) < 0)
				return -1;
		}

		extra->dataloopstart = mupp[i].dataloopstart;
		extra->dataloopend = mupp[i].dataloopend;

		hio_read(extra->data, 1, 64, f);
		hio_read(extra->progvolume, 1, 64, f);

		mupp_index++;
	}

	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;
}
Example #30
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;
}