Exemple #1
0
void xmp_scan_module(xmp_context opaque)
{
	struct context_data *ctx = (struct context_data *)opaque;

	if (ctx->state < XMP_STATE_LOADED)
		return;

	scan_sequences(ctx);
}
Exemple #2
0
static int load_module(xmp_context opaque, HIO_HANDLE *h, struct list_head *tmpfiles_list)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	int i, ret;
	int test_result, load_result;

	load_prologue(ctx);

	D_(D_WARN "load");
	test_result = load_result = -1;
	for (i = 0; format_loader[i] != NULL; i++) {
		hio_seek(h, 0, SEEK_SET);
		test_result = format_loader[i]->test(h, NULL, 0);
		if (test_result == 0) {
			hio_seek(h, 0, SEEK_SET);
			D_(D_WARN "load format: %s", format_loader[i]->name);
			load_result = format_loader[i]->loader(m, h, 0);
			break;
		}
	}

	if (test_result == 0 && load_result == 0)
		set_md5sum(h, m->md5);

	hio_close(h);
	if (tmpfiles_list != NULL)
		unlink_tempfiles(tmpfiles_list);

	if (test_result < 0) {
		free(m->basename);
		free(m->dirname);
		return -XMP_ERROR_FORMAT;
	}

	if (load_result < 0) {
		xmp_release_module(opaque);
		return -XMP_ERROR_LOAD;
	}

	str_adj(m->mod.name);
	load_epilogue(ctx);

	ret = prepare_scan(ctx);
	if (ret < 0)
		return ret;

	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;

	return 0;
}
Exemple #3
0
void create_simple_module(struct context_data *ctx, int ins, int pat)
{
	struct module_data *m = &ctx->m;
	struct xmp_module *mod = &m->mod;
	int i;

	load_prologue(ctx);

	/* Create module */

	mod->len = 2;
	mod->pat = pat;
	mod->ins = ins;
	mod->chn = 4;
	mod->trk = mod->pat * mod->chn;
	mod->smp = mod->ins;
	mod->xxo[0] = 0;
	mod->xxo[1] = 1;

	pattern_init(mod);

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

	instrument_init(mod);

	for (i = 0; i < mod->ins; i++) {
		mod->xxi[i].nsm = 1;
		subinstrument_alloc(mod, i, 1);

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

		mod->xxs[i].len = 10000;
		mod->xxs[i].lps = 0;
		mod->xxs[i].lpe = 10000;
		mod->xxs[i].flg = XMP_SAMPLE_LOOP;
		mod->xxs[i].data = calloc(1, 10000);
		mod->xxs[i].data += 4;
	}

	/* End of module creation */

	load_epilogue(ctx);
	prepare_scan(ctx);
	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;
}
Exemple #4
0
static void module_quirks(struct context_data *ctx)
{
	struct player_data *p = &ctx->p;
	struct module_data *m = &ctx->m;
	int i;

	for (i = 0; mq[i].flags != 0; i++) {
		if (!memcmp(m->md5, mq[i].md5, 16)) {
			p->flags |= mq[i].flags;

			if (mq[i].flags & XMP_FLAGS_VBLANK)
				scan_sequences(ctx);
			return;
		}
	}
}
Exemple #5
0
void load_epilogue(struct context_data *ctx)
{
	struct player_data *p = &ctx->p;
	struct module_data *m = &ctx->m;
	int i, j;

    	m->mod.gvl = m->gvolbase;

	/* Fix cases where the restart value is invalid e.g. kc_fall8.xm
	 * from http://aminet.net/mods/mvp/mvp_0002.lha (reported by
	 * Ralf Hoffmann <*****@*****.**>)
	 */
	if (m->mod.rst >= m->mod.len) {
		m->mod.rst = 0;
	}

	/* Sanity check */
	if (m->mod.spd == 0) {
		m->mod.spd = 6;
	}
	if (m->mod.bpm == 0) {
		m->mod.bpm = 125;
	}

	/* Set appropriate values for instrument volumes and subinstrument
	 * global volumes when QUIRK_INSVOL is not set, to keep volume values
	 * consistent if the user inspects struct xmp_module. We can later
	 * set volumes in the loaders and eliminate the quirk.
	 */
	for (i = 0; i < m->mod.ins; i++) {
		if (~m->quirk & QUIRK_INSVOL) {
			m->mod.xxi[i].vol = m->volbase;
		}
		for (j = 0; j < m->mod.xxi[i].nsm; j++) {
			if (~m->quirk & QUIRK_INSVOL) {
				m->mod.xxi[i].sub[j].gvl = m->volbase;
			}
		}
	}

	p->flags = p->player_flags;
	module_quirks(ctx);

	scan_sequences(ctx);
}
Exemple #6
0
static int module_load(HIO_HANDLE* h, struct context_data *ctx, const struct format_loader* format)
{
	struct module_data *m = &ctx->m;

	hio_seek(h, 0, SEEK_SET);
	if (format->loader(m, h, 0) < 0)
	  return -XMP_ERROR_LOAD;

	str_adj(m->mod.name);
	str_adj(m->mod.author);

	load_epilogue(ctx);

	if (prepare_scan(ctx) < 0)
	  return -XMP_ERROR_LOAD;

	scan_sequences(ctx);
	ctx->state = XMP_STATE_LOADED;
	set_md5sum(h, m->md5);
	return 0;
}
Exemple #7
0
int xmp_set_player__(xmp_context opaque, int parm, int val)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct player_data *p = &ctx->p;
	struct module_data *m = &ctx->m;
	struct mixer_data *s = &ctx->s;
	int ret = -XMP_ERROR_INVALID;

	if (ctx->state < XMP_STATE_PLAYING)
		return -XMP_ERROR_STATE;

	switch (parm) {
	case XMP_PLAYER_AMP:
		if (val >= 0 && val <= 3) {
			s->amplify = val;
			ret = 0;
		}
		break;
	case XMP_PLAYER_MIX:
		if (val >= -100 && val <= 100) {
			s->mix = val;
			ret = 0;
		}
		break;
	case XMP_PLAYER_INTERP:
		if (val >= XMP_INTERP_NEAREST && val <= XMP_INTERP_SPLINE) {
			s->interp = val;
			ret = 0;
		}
		break;
	case XMP_PLAYER_DSP:
		s->dsp = val;
		ret = 0;
		break;
	case XMP_PLAYER_FLAGS: {
		int vblank = p->flags & XMP_FLAGS_VBLANK;
		p->player_flags = val;
		p->flags |= val;
		if (vblank != (p->flags & XMP_FLAGS_VBLANK))
			scan_sequences(ctx);
		ret = 0;
		break; }
	case XMP_PLAYER_CFLAGS: {
		int vblank = p->flags & XMP_FLAGS_VBLANK;
		p->flags = val;
		if (vblank != (p->flags & XMP_FLAGS_VBLANK))
			scan_sequences(ctx);
		ret = 0;
		break; }
	case XMP_PLAYER_SMPCTL:
		m->smpctl = val;
		ret = 0;
		break;
	case XMP_PLAYER_VOLUME:
		if (val >= 0 && val <= 200) {
			p->master_vol = val;
			ret = 0;
		}
		break;
	case XMP_PLAYER_SMIX_VOLUME:
		if (val >= 0 && val <= 200) {
			p->smix_vol = val;
			ret = 0;
		}
		break;
	}

	return ret;
}
Exemple #8
0
int xmp_load_module(xmp_context opaque, char *path)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	HIO_HANDLE *h;
	struct stat st;
	struct list_head tmpfiles_list;
	int test_result, load_result;
	int i, ret;

	D_(D_WARN "path = %s", path);

	if (stat(path, &st) < 0)
		return -XMP_ERROR_SYSTEM;

#ifndef _MSC_VER
	if (S_ISDIR(st.st_mode)) {
		errno = EISDIR;
		return -XMP_ERROR_SYSTEM;
	}
#endif

	if ((h = hio_open_file(path, "rb")) == NULL)
		return -XMP_ERROR_SYSTEM;

	INIT_LIST_HEAD(&tmpfiles_list);

	D_(D_INFO "decrunch");
	if (decrunch(&tmpfiles_list, &h->f, &path, DECRUNCH_MAX) < 0)
		goto err_depack;

	if (hio_stat(h, &st) < 0)
		goto err_depack;

	if (st.st_size < 256) {			/* get size after decrunch */
		hio_close(h);
		unlink_tempfiles(&tmpfiles_list);
		return -XMP_ERROR_FORMAT;
	}

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

	m->dirname = get_dirname(path);
	if (m->dirname == NULL)
		return -XMP_ERROR_SYSTEM;

	m->basename = get_basename(path);
	if (m->basename == NULL)
		return -XMP_ERROR_SYSTEM;

	m->filename = path;	/* For ALM, SSMT, etc */
	m->size = st.st_size;

	load_prologue(ctx);

	D_(D_WARN "load");
	test_result = load_result = -1;
	for (i = 0; format_loader[i] != NULL; i++) {
		hio_seek(h, 0, SEEK_SET);
		test_result = format_loader[i]->test(h, NULL, 0);
		if (test_result == 0) {
			hio_seek(h, 0, SEEK_SET);
			D_(D_WARN "load format: %s", format_loader[i]->name);
			load_result = format_loader[i]->loader(m, h, 0);
			break;
		}
	}

	set_md5sum(h, m->md5);

	hio_close(h);
	unlink_tempfiles(&tmpfiles_list);

	if (test_result < 0) {
		free(m->basename);
		free(m->dirname);
		return -XMP_ERROR_FORMAT;
	}

	if (load_result < 0) {
		xmp_release_module(opaque);
		return -XMP_ERROR_LOAD;
	}

	str_adj(m->mod.name);
	if (!*m->mod.name) {
		strncpy(m->mod.name, m->basename, XMP_NAME_SIZE);
	}

	load_epilogue(ctx);

	ret = prepare_scan(ctx);
	if (ret < 0)
		return ret;

	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;

	return 0;

    err_depack:
	hio_close(h);
	unlink_tempfiles(&tmpfiles_list);
	return -XMP_ERROR_DEPACK;
}
Exemple #9
0
static int load_module(xmp_context opaque, HIO_HANDLE *h)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	struct xmp_module *mod = &m->mod;
	int i, j, ret;
	int test_result, load_result;

	load_prologue(ctx);

	D_(D_WARN "load");
	test_result = load_result = -1;
	for (i = 0; format_loader[i] != NULL; i++) {
		hio_seek(h, 0, SEEK_SET);
		D_(D_WARN "test %s", format_loader[i]->name);
		test_result = format_loader[i]->test(h, NULL, 0);
		if (test_result == 0) {
			hio_seek(h, 0, SEEK_SET);
			D_(D_WARN "load format: %s", format_loader[i]->name);
			load_result = format_loader[i]->loader(m, h, 0);
			break;
		}
	}

#ifndef LIBXMP_CORE_PLAYER
	if (test_result == 0 && load_result == 0)
		set_md5sum(h, m->md5);
#endif

	if (test_result < 0) {
		free(m->basename);
		free(m->dirname);
		return -XMP_ERROR_FORMAT;
	}

	if (load_result < 0) {
		goto err_load;
	}

	/* Sanity check */
	if (mod->chn > XMP_MAX_CHANNELS || mod->len > XMP_MAX_MOD_LENGTH) {
		goto err_load;
	}

	/* Sanity check */
	if (mod->xxp == NULL) {
		goto err_load;
	}
	for (i = 0; i < mod->pat; i++) {
		if (mod->xxp[i] == NULL) {
			goto err_load;
		}
		for (j = 0; j < mod->chn; j++) {
			int t = mod->xxp[i]->index[j];
			if (t < 0 || t >= mod->trk || mod->xxt[t] == NULL) {
				goto err_load;
			}
		}
	}

	adjust_string(mod->name);
	load_epilogue(ctx);

	ret = prepare_scan(ctx);
	if (ret < 0) {
		xmp_release_module(opaque);
		return ret;
	}

	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;

	return 0;

    err_load:
	xmp_release_module(opaque);
	return -XMP_ERROR_LOAD;
}
Exemple #10
0
int xmp_create_module(xmp_context opaque, int nch)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	struct xmp_module *mod = &m->mod;
	int i;

	if (nch < 0 || nch > 64)
		return -XMP_ERROR_INVALID;

	m->filename = NULL;
	m->basename = NULL;
	m->size = 0;

	if (ctx->state > XMP_STATE_UNLOADED)
		xmp_release_module(opaque);

	load_prologue(ctx);

	mod->pat = 1;
	mod->len = mod->pat;
	mod->ins = 0;
	mod->smp = 0;
	mod->chn = nch;
	mod->trk = mod->pat * mod->chn;
	mod->xxo[0] = 0;
	mod->xxp = calloc(mod->pat, sizeof (struct xmp_pattern *));
	if (mod->xxp == NULL)
		goto err;
	mod->xxt = calloc(mod->trk, sizeof (struct xmp_track *));
	if (mod->xxt == NULL)
		goto err1;

	for (i = 0; i < mod->pat; i++) {
		mod->xxp[i] = calloc(1, sizeof (struct xmp_pattern) +
					(nch - 1) * sizeof(int));
		if (mod->xxp[i] == NULL)
			goto err2;
		mod->xxp[i]->rows = 64;
	}

	for (i = 0; i < mod->trk; i++) {
		mod->xxt[i] = calloc(1, sizeof (struct xmp_track) +
			(mod->xxp[0]->rows - 1) * sizeof (struct xmp_event));
		if (mod->xxt[i] == NULL)
			goto err3;
        	mod->xxp[i / nch]->index[i % nch] = i;
        	mod->xxt[i] = calloc (sizeof (struct xmp_track) + sizeof
			(struct xmp_event) * (mod->xxp[i / nch]->rows - 1), 1);
		mod->xxt[i]->rows = 64;
	}

	load_epilogue(ctx);

	ret = prepare_scan(ctx);
	if (ret < 0)
		return ret;

	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;

	return 0;

    err3:
	for (i = 0; i < mod->trk; i++)
		free(mod->xxt[i]);
    err2:
	for (i = 0; i < mod->pat; i++)
		free(mod->xxp[i]);
	free(mod->xxt);
    err1:
        free(mod->xxp);
    err:
	return XMP_ERROR_INTERNAL;
}