Example #1
0
/* Loads all patterns of a modfile and converts them into the 3 byte format. */
static BOOL ML_LoadPatterns(void)
{
	int t, s, tracks = 0;

	if (!AllocPatterns()) {
		return 0;
	}
	if (!AllocTracks()) {
		return 0;
	}

	/* Allocate temporary buffer for loading and converting the patterns */
	if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
		return 0;


	/* patterns start here */
	_mm_fseek(modreader, 0xA66, SEEK_SET);
	for (t = 0; t < of.numpat; t++) {
		/* Load the pattern into the temp buffer and convert it */
		for (s = 0; s < (64U * of.numchn); s++) {
			patbuf[s].a = _mm_read_UBYTE(modreader);
			patbuf[s].b = _mm_read_UBYTE(modreader);
			patbuf[s].c = _mm_read_UBYTE(modreader);
			patbuf[s].d = _mm_read_UBYTE(modreader);
		}
		for (s = 0; s < of.numchn; s++) {
			if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s))) {
				return 0;
			}
		}
	}
	return 1;
}
static BOOL ML_LoadPatterns(void)
/*
	Loads all patterns of a modfile and converts them into the
	3 byte format.
*/
{
    int t,s,tracks=0;

    if(!AllocPatterns()) return 0;
    if(!AllocTracks()) return 0;

    /* Allocate temporary buffer for loading
       and converting the patterns */

    if(!(patbuf=(MODNOTE *)MyCalloc(64U*of.numchn,sizeof(MODNOTE)))) return 0;

    for(t=0;t<of.numpat;t++){

	/* Load the pattern into the temp buffer
	   and convert it */

	for(s=0;s<(64L * of.numchn);s++){
	    patbuf[s].a=_mm_read_UBYTE();
	    patbuf[s].b=_mm_read_UBYTE();
	    patbuf[s].c=_mm_read_UBYTE();
	    patbuf[s].d=_mm_read_UBYTE();
	}

	for(s=0;s<of.numchn;s++){
	    if(!(of.tracks[tracks++]=ConvertTrack(patbuf+s))) return 0;
	}
    }

    return 1;
}
Example #3
0
static BOOL OKT_doPBOD(int patnum)
{
	char *patbuf;
	int rows, i;
	int u;

	if (!patnum) {
		of.numtrk = of.numpat * of.numchn;

		if (!AllocTracks() || !AllocPatterns())
			return 0;
	}

	/* Read pattern */
	of.pattrows[patnum] = rows = _mm_read_M_UWORD(modreader);

	if (!(okttrk = (OKTNOTE *) _mm_calloc(rows, sizeof(OKTNOTE))) ||
	    !(patbuf = (char *)_mm_calloc(rows * of.numchn, sizeof(OKTNOTE))))
		return 0;
	_mm_read_UBYTES(patbuf, rows * of.numchn * sizeof(OKTNOTE), modreader);
	if (_mm_eof(modreader)) {
		_mm_errno = MMERR_LOADING_PATTERN;
		return 0;
	}

	for (i = 0; i < of.numchn; i++) {
		for (u = 0; u < rows; u++) {
			okttrk[u].note = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE)];
			okttrk[u].ins = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 1];
			okttrk[u].eff = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 2];
			okttrk[u].dat = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 3];
		}

		if (!(of.tracks[patnum * of.numchn + i] = OKT_ConvertTrack(rows)))
			return 0;
	}
	_mm_free(patbuf);
	_mm_free(okttrk);
	return 1;
}
Example #4
0
BOOL 
FAR_Load (BOOL curious)
{
  int t, u, tracks = 0;
  SAMPLE *q;
  FARSAMPLE s;
  FARNOTE *crow;
  UBYTE smap[8];

  /* try to read module header (first part) */
  _mm_read_UBYTES (mh1->id, 4, modreader);
  _mm_read_SBYTES (mh1->songname, 40, modreader);
  _mm_read_SBYTES (mh1->blah, 3, modreader);
  mh1->headerlen = _mm_read_I_UWORD (modreader);
  mh1->version = _mm_read_UBYTE (modreader);
  _mm_read_UBYTES (mh1->onoff, 16, modreader);
  _mm_read_UBYTES (mh1->edit1, 9, modreader);
  mh1->speed = _mm_read_UBYTE (modreader);
  _mm_read_UBYTES (mh1->panning, 16, modreader);
  _mm_read_UBYTES (mh1->edit2, 4, modreader);
  mh1->stlen = _mm_read_I_UWORD (modreader);

  /* init modfile data */
  of.modtype = strdup (FAR_Version);
  of.songname = DupStr (mh1->songname, 40, 1);
  of.numchn = 16;
  of.initspeed = mh1->speed;
  of.inittempo = 80;
  of.reppos = 0;
  for (t = 0; t < 16; t++)
    of.panning[t] = mh1->panning[t] << 4;

  /* read songtext into comment field */
  if (mh1->stlen)
    if (!ReadComment (mh1->stlen))
      return 0;

  /* try to read module header (second part) */
  _mm_read_UBYTES (mh2->orders, 256, modreader);
  mh2->numpat = _mm_read_UBYTE (modreader);
  mh2->snglen = _mm_read_UBYTE (modreader);
  mh2->loopto = _mm_read_UBYTE (modreader);
  _mm_read_I_UWORDS (mh2->patsiz, 256, modreader);

  of.numpos = mh2->snglen;
  if (!AllocPositions (of.numpos))
    return 0;
  for (t = 0; t < of.numpos; t++)
    {
      if (mh2->orders[t] == 0xff)
	break;
      of.positions[t] = mh2->orders[t];
    }

  /* count number of patterns stored in file */
  of.numpat = 0;
  for (t = 0; t < 256; t++)
    if (mh2->patsiz[t])
      if ((t + 1) > of.numpat)
	of.numpat = t + 1;
  of.numtrk = of.numpat * of.numchn;

  /* seek across eventual new data */
  _mm_fseek (modreader, mh1->headerlen - (869 + mh1->stlen), SEEK_CUR);

  /* alloc track and pattern structures */
  if (!AllocTracks ())
    return 0;
  if (!AllocPatterns ())
    return 0;

  for (t = 0; t < of.numpat; t++)
    {
      UBYTE rows = 0;

      memset (pat, 0, 256 * 16 * 4 * sizeof (FARNOTE));
      if (mh2->patsiz[t])
	{
	  rows = _mm_read_UBYTE (modreader);
	  /* tempo = */ _mm_read_UBYTE (modreader);

	  crow = pat;
	  /* file often allocates 64 rows even if there are less in pattern */
	  if (mh2->patsiz[t] < 2 + (rows * 16 * 4))
	    {
	      _mm_errno = MMERR_LOADING_PATTERN;
	      return 0;
	    }
	  for (u = (mh2->patsiz[t] - 2) / 4; u; u--, crow++)
	    {
	      crow->note = _mm_read_UBYTE (modreader);
	      crow->ins = _mm_read_UBYTE (modreader);
	      crow->vol = _mm_read_UBYTE (modreader);
	      crow->eff = _mm_read_UBYTE (modreader);
	    }

	  if (_mm_eof (modreader))
	    {
	      _mm_errno = MMERR_LOADING_PATTERN;
	      return 0;
	    }

	  crow = pat;
	  of.pattrows[t] = rows;
	  for (u = 16; u; u--, crow++)
	    if (!(of.tracks[tracks++] = FAR_ConvertTrack (crow, rows)))
	      {
		_mm_errno = MMERR_LOADING_PATTERN;
		return 0;
	      }
	}
      else
	tracks += 16;
    }

  /* read sample map */
  if (!_mm_read_UBYTES (smap, 8, modreader))
    {
      _mm_errno = MMERR_LOADING_HEADER;
      return 0;
    }

  /* count number of samples used */
  of.numins = 0;
  for (t = 0; t < 64; t++)
    if (smap[t >> 3] & (1 << (t & 7)))
      of.numins = t + 1;
  of.numsmp = of.numins;

  /* alloc sample structs */
  if (!AllocSamples ())
    return 0;

  q = of.samples;
  for (t = 0; t < of.numsmp; t++)
    {
      q->speed = 8363;
      q->flags = SF_SIGNED;
      if (smap[t >> 3] & (1 << (t & 7)))
	{
	  _mm_read_SBYTES (s.samplename, 32, modreader);
	  s.length = _mm_read_I_ULONG (modreader);
	  s.finetune = _mm_read_UBYTE (modreader);
	  s.volume = _mm_read_UBYTE (modreader);
	  s.reppos = _mm_read_I_ULONG (modreader);
	  s.repend = _mm_read_I_ULONG (modreader);
	  s.type = _mm_read_UBYTE (modreader);
	  s.loop = _mm_read_UBYTE (modreader);

	  q->samplename = DupStr (s.samplename, 32, 1);
	  q->length = s.length;
	  q->loopstart = s.reppos;
	  q->loopend = s.repend;
	  q->volume = s.volume << 2;

	  if (s.type & 1)
	    q->flags |= SF_16BITS;
	  if (s.loop & 8)
	    q->flags |= SF_LOOP;

	  q->seekpos = _mm_ftell (modreader);
	  _mm_fseek (modreader, q->length, SEEK_CUR);
	}
      else
	q->samplename = DupStr (NULL, 0, 0);
      q++;
    }
Example #5
0
static BOOL S69_LoadPatterns(void)
{
	int track,row,channel;
	UBYTE note,inst,vol,effect,lastfx,lastval;
	S69NOTE *cur;
	int tracks=0;
	
	if(!AllocPatterns()) return 0;
	if(!AllocTracks()) return 0;

	for(track=0;track<of.numpat;track++) {
		/* set pattern break locations */
		of.pattrows[track]=mh->breaks[track]+1;

		/* load the 669 pattern */
		cur=s69pat;
		for(row=0;row<64;row++) {
			for(channel=0;channel<8;channel++,cur++) {
				cur->a = _mm_read_UBYTE(modreader);
				cur->b = _mm_read_UBYTE(modreader);
				cur->c = _mm_read_UBYTE(modreader);
			}
		}

		if(_mm_eof(modreader)) {
			_mm_errno = MMERR_LOADING_PATTERN;
			return 0;
		}

		/* translate the pattern */
		for(channel=0;channel<8;channel++) {
			UniReset();
			/* set pattern tempo */
			UniPTEffect(0xf,78);
			UniPTEffect(0xf,mh->tempos[track]);

			lastfx=0xff,lastval=0;

			for(row=0;row<=mh->breaks[track];row++) {
				int a,b,c;

				/* fetch the encoded note */
				a=s69pat[(row*8)+channel].a;
				b=s69pat[(row*8)+channel].b;
				c=s69pat[(row*8)+channel].c;

				/* decode it */
				note=a>>2;
				inst=((a&0x3)<<4)|((b&0xf0)>>4);
				vol=b&0xf;

				if (a<0xff) {
					if (a<0xfe) {
						UniInstrument(inst);
						UniNote(note+2*OCTAVE);
						lastfx=0xff; /* reset background effect memory */
					}
					UniPTEffect(0xc,vol<<2);
				}

				if ((c!=0xff)||(lastfx!=0xff)) {
					if(c==0xff)
						c=lastfx,effect=lastval;
					else
						effect=c&0xf;

					switch(c>>4) {
						case 0: /* porta up */
							UniPTEffect(0x1,effect);
							lastfx=c,lastval=effect;
							break;
						case 1: /* porta down */
							UniPTEffect(0x2,effect);
							lastfx=c,lastval=effect;
							break;
						case 2: /* porta to note */
							UniPTEffect(0x3,effect);
							lastfx=c,lastval=effect;
							break;
						case 3: /* frequency adjust */
							/* DMP converts this effect to S3M FF1. Why not ? */
							UniEffect(UNI_S3MEFFECTF,0xf0|effect);
							break;
						case 4: /* vibrato */
							UniPTEffect(0x4,effect);
							lastfx=c,lastval=effect;
							break;
						case 5: /* set speed */
							if (effect)
								UniPTEffect(0xf,effect);
							else 
							  if(mh->marker[0]!=0x69) {
#ifdef MIKMOD_DEBUG
								fprintf(stderr,"\r669: unsupported super fast tempo at pat=%d row=%d chan=%d\n",
								       track,row,channel);
#endif
							}
							break;
					}
				}
				UniNewline();
			}
			if(!(of.tracks[tracks++]=UniDup())) return 0;
		}
	}

	return 1;
}
Example #6
0
BOOL 
DSM_Load (BOOL curious)
{
  int t;
  DSMINST s;
  SAMPLE *q;
  int cursmp = 0, curpat = 0, track = 0;

  blocklp = 0;
  blockln = 12;

  if (!GetBlockHeader ())
    return 0;
  if (memcmp (blockid, SONGID, 4))
    {
      _mm_errno = MMERR_LOADING_HEADER;
      return 0;
    }

  _mm_read_UBYTES (mh->songname, 28, modreader);
  mh->version = _mm_read_I_UWORD (modreader);
  mh->flags = _mm_read_I_UWORD (modreader);
  mh->reserved2 = _mm_read_I_ULONG (modreader);
  mh->numord = _mm_read_I_UWORD (modreader);
  mh->numsmp = _mm_read_I_UWORD (modreader);
  mh->numpat = _mm_read_I_UWORD (modreader);
  mh->numtrk = _mm_read_I_UWORD (modreader);
  mh->globalvol = _mm_read_UBYTE (modreader);
  mh->mastervol = _mm_read_UBYTE (modreader);
  mh->speed = _mm_read_UBYTE (modreader);
  mh->bpm = _mm_read_UBYTE (modreader);
  _mm_read_UBYTES (mh->panpos, DSM_MAXCHAN, modreader);
  _mm_read_UBYTES (mh->orders, DSM_MAXORDERS, modreader);

  /* set module variables */
  of.initspeed = mh->speed;
  of.inittempo = mh->bpm;
  of.modtype = strdup (DSM_Version);
  of.numchn = mh->numtrk;
  of.numpat = mh->numpat;
  of.numtrk = of.numchn * of.numpat;
  of.songname = DupStr (mh->songname, 28, 1);	/* make a cstr of songname */
  of.reppos = 0;

  for (t = 0; t < DSM_MAXCHAN; t++)
    of.panning[t] = mh->panpos[t] == DSM_SURROUND ? PAN_SURROUND :
      mh->panpos[t] < 0x80 ? (mh->panpos[t] << 1) : 255;

  if (!AllocPositions (mh->numord))
    return 0;
  of.numpos = 0;
  for (t = 0; t < mh->numord; t++)
    {
      of.positions[of.numpos] = mh->orders[t];
      if (mh->orders[t] < 254)
	of.numpos++;
    }

  of.numins = of.numsmp = mh->numsmp;

  if (!AllocSamples ())
    return 0;
  if (!AllocTracks ())
    return 0;
  if (!AllocPatterns ())
    return 0;

  while (cursmp < of.numins || curpat < of.numpat)
    {
      if (!GetBlockHeader ())
	return 0;
      if (!memcmp (blockid, INSTID, 4) && cursmp < of.numins)
	{
	  q = &of.samples[cursmp];

	  /* try to read sample info */
	  _mm_read_UBYTES (s.filename, 13, modreader);
	  s.flags = _mm_read_I_UWORD (modreader);
	  s.volume = _mm_read_UBYTE (modreader);
	  s.length = _mm_read_I_ULONG (modreader);
	  s.loopstart = _mm_read_I_ULONG (modreader);
	  s.loopend = _mm_read_I_ULONG (modreader);
	  s.reserved1 = _mm_read_I_ULONG (modreader);
	  s.c2spd = _mm_read_I_UWORD (modreader);
	  s.period = _mm_read_I_UWORD (modreader);
	  _mm_read_UBYTES (s.samplename, 28, modreader);

	  q->samplename = DupStr (s.samplename, 28, 1);
	  q->seekpos = _mm_ftell (modreader);
	  q->speed = s.c2spd;
	  q->length = s.length;
	  q->loopstart = s.loopstart;
	  q->loopend = s.loopend;
	  q->volume = s.volume;

	  if (s.flags & 1)
	    q->flags |= SF_LOOP;
	  if (s.flags & 2)
	    q->flags |= SF_SIGNED;
	  /* (s.flags&4) means packed sample,
	     but did they really exist in dsm ? */
	  cursmp++;
	}
      else if (!memcmp (blockid, PATTID, 4) && curpat < of.numpat)
	{
	  DSM_ReadPattern ();
	  for (t = 0; t < of.numchn; t++)
	    if (!(of.tracks[track++] = DSM_ConvertTrack (&dsmbuf[t * 64])))
	      return 0;
	  curpat++;
	}
    }

  return 1;
}
Example #7
0
static BOOL S3M_Load(void)
{
    int t,u,track=0;
    INSTRUMENT *d;
    SAMPLE *q;
    UBYTE isused[16];
    UBYTE pan[32];

    /* try to read module header */

    _mm_read_str(mh_s3m->songname,28);
    mh_s3m->t1a			=_mm_read_UBYTE();
    mh_s3m->type		=_mm_read_UBYTE();
    _mm_read_UBYTES(mh_s3m->unused1,2);
    mh_s3m->ordnum		=_mm_read_I_UWORD();
    mh_s3m->insnum		=_mm_read_I_UWORD();
    mh_s3m->patnum		=_mm_read_I_UWORD();
    mh_s3m->flags		=_mm_read_I_UWORD();
    mh_s3m->tracker		=_mm_read_I_UWORD();
    mh_s3m->fileformat	=_mm_read_I_UWORD();
    _mm_read_str(mh_s3m->scrm,4);

    mh_s3m->mastervol	=_mm_read_UBYTE();
    mh_s3m->initspeed	=_mm_read_UBYTE();
    mh_s3m->inittempo	=_mm_read_UBYTE();
    mh_s3m->mastermult	=_mm_read_UBYTE();
    mh_s3m->ultraclick	=_mm_read_UBYTE();
    mh_s3m->pantable	=_mm_read_UBYTE();
    _mm_read_UBYTES(mh_s3m->unused2,8);
    mh_s3m->special		=_mm_read_I_UWORD();
    _mm_read_UBYTES(mh_s3m->channels,32);

    if(modpos > modsize){
	gModPlayerErrorMessage=ERROR_LOADING_HEADER;
	return 0;
    }

    /* set module variables */

    of.modtype=strdup(S3M_Version);
    of.songname=DupStr(mh_s3m->songname,28);    /* make a cstr of songname */
    of.numpat=mh_s3m->patnum;
    of.numins=mh_s3m->insnum;
    of.initspeed=mh_s3m->initspeed;
    of.inittempo=mh_s3m->inittempo;

    /* count the number of channels used */

    of.numchn=0;

    /*      for(t=0;t<32;t++) printf("%2.2x ",mh_s3m->channels[t]);
     */
    for(t=0;t<32;t++) remap[t]=0;
    for(t=0;t<16;t++) isused[t]=0;

    /* set a flag for each channel (1 out of of 16) thats being used: */

    for(t=0;t<32;t++){
	if(mh_s3m->channels[t]<16){
	    isused[mh_s3m->channels[t]]=1;
	}
    }

    /* give each of them a different number */

    for(t=0;t<16;t++){
	if(isused[t]){
	    isused[t]=of.numchn;
	    of.numchn++;
	}
    }

    /* build the remap array */

    for(t=0;t<32;t++){
	if(mh_s3m->channels[t]<16){
	    remap[t]=isused[mh_s3m->channels[t]];
	}
    }

    /* set panning positions */

    for(t=0;t<32;t++){
	if(mh_s3m->channels[t]<16){
	    if(mh_s3m->channels[t]<8){
		of.panning[remap[t]]=0x30;
	    }
	    else{
		of.panning[remap[t]]=0xc0;
	    }
	}
    }

    of.numtrk=of.numpat*of.numchn;

    /*      printf("Uses %d channels\n",of.numchn);
     */
    /* read the order data */

    _mm_read_UBYTES(of.positions,mh_s3m->ordnum);

    of.numpos=0;
    for(t=0;t<mh_s3m->ordnum;t++){
	of.positions[of.numpos]=of.positions[t];
	if(of.positions[t]<254) of.numpos++;
    }

    if((paraptr=(UWORD *)MyMalloc((of.numins+of.numpat)*sizeof(UWORD)))==NULL) return 0;

    /* read the instrument+pattern parapointers */

    _mm_read_I_UWORDS(paraptr,of.numins+of.numpat);

    /*      printf("pantab %d\n",mh_s3m->pantable);
     */
    if(mh_s3m->pantable==252){

	/* read the panning table */

	_mm_read_UBYTES(pan,32);

	/* set panning positions according to panning table (new for st3.2) */

	for(t=0;t<32;t++){
	    if((pan[t]&0x20) && mh_s3m->channels[t]<16){
		of.panning[remap[t]]=(pan[t]&0xf)<<4;
	    }
	}
    }

    /* now is a good time to check if the header was too short :) */

    if(modpos > modsize){
	gModPlayerErrorMessage=ERROR_LOADING_HEADER;
	return 0;
    }

    if(!AllocInstruments()) return 0;

    d=of.instruments;

    for(t=0;t<of.numins;t++){
	S3MSAMPLE s;

	d->numsmp=1;
	if(!AllocSamples(d)) return 0;
	q=d->samples;

	/* seek to instrument position */

	_mm_fseek(((long)paraptr[t])<<4,SEEK_SET);

	/* and load sample info */

	s.type		=_mm_read_UBYTE();
	_mm_read_str(s.filename,12);
	s.memsegh	=_mm_read_UBYTE();
	s.memsegl	=_mm_read_I_UWORD();
	s.length	=_mm_read_I_ULONG();
	s.loopbeg	=_mm_read_I_ULONG();
	s.loopend	=_mm_read_I_ULONG();
	s.volume	=_mm_read_UBYTE();
	s.dsk 		=_mm_read_UBYTE();
	s.pack		=_mm_read_UBYTE();
	s.flags		=_mm_read_UBYTE();
	s.c2spd		=_mm_read_I_ULONG();
	_mm_read_UBYTES(s.unused,12);
	_mm_read_str(s.sampname,28);
	_mm_read_str(s.scrs,4);

	if(modpos > modsize){
	    gModPlayerErrorMessage=ERROR_LOADING_HEADER;
	    return 0;
	}

	d->insname=DupStr(s.sampname,28);
	q->c2spd= (unsigned short)s.c2spd;
	q->length=s.length;
	q->loopstart=s.loopbeg;
	q->loopend=s.loopend;
	q->volume=s.volume;
	q->seekpos=(((long)s.memsegh)<<16|s.memsegl)<<4;

	q->flags=0;

	if(s.flags&1) q->flags|=SF_LOOP;
	if(s.flags&4) q->flags|=SF_16BITS;
	if(mh_s3m->fileformat==1) q->flags|=SF_SIGNED;

	/* DON'T load sample if it doesn't have the SCRS tag */

	if(memcmp(s.scrs,"SCRS",4)!=0) q->length=0;

	/*              printf("%s\n",d->insname);
	 */
	d++;
    }

    if(!AllocTracks()) 
	{
	    gModPlayerErrorMessage=ERROR_ALLOC_STRUCT;
	    return 0;
	}
    if(!AllocPatterns()) 
	{
	    gModPlayerErrorMessage=ERROR_ALLOC_STRUCT;
	    return 0;
	}

    for(t=0;t<of.numpat;t++)
	{
	    /* seek to pattern position ( + 2 skip pattern length ) */
		
	    _mm_fseek((((long)paraptr[of.numins+t])<<4)+2,SEEK_SET);

	    if(!S3M_ReadPattern())
		{
		    gModPlayerErrorMessage = ERROR_LOADING_PATTERN;
		    return 0;
		}
	    for(u=0;u<of.numchn;u++)
		{
		    if(!(of.tracks[track++]=S3M_ConvertTrack(&s3mbuf[u*64]))) 
			{
			    gModPlayerErrorMessage = ERROR_LOADING_TRACK;
			    return 0;
			}
		}
	}

    return 1;
}
Example #8
0
ap_result MikSTX::ModuleConverter(APAgent_ConvertModule *convInfo)
{
	int32 t, u, track = 0;
	int32 version = 0;
	SAMPLE *q;
	PFile *file = convInfo->moduleFile;
	ap_result retVal = AP_OK;

	try
	{
		// Clear the buffer pointers
		mh        = NULL;
		stxBuf    = NULL;
		posLookup = NULL;
		paraPtr   = NULL;

		// Allocate buffers
		if ((mh = new STXHEADER) == NULL)
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		if ((stxBuf = new STXNOTE[4 * 64]) == NULL)
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		if ((posLookup = new uint8[256]) == NULL)
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		// Clear the buffers
		memset(mh, 0, sizeof(STXHEADER));
		memset(stxBuf, 0, sizeof(STXNOTE) * 4 * 64);
		memset(posLookup, -1, 256);

		// Try to read module header
		file->ReadString(mh->songName, 20);
		file->ReadString(mh->trackerName, 8);

		mh->patSize    = file->Read_L_UINT16();
		mh->unknown1   = file->Read_L_UINT16();
		mh->patPtr     = file->Read_L_UINT16();
		mh->insPtr     = file->Read_L_UINT16();
		mh->chnPtr     = file->Read_L_UINT16();
		mh->unknown2   = file->Read_L_UINT16();
		mh->unknown3   = file->Read_L_UINT16();
		mh->masterMult = file->Read_UINT8();
		mh->initSpeed  = file->Read_UINT8() >> 4;
		mh->unknown4   = file->Read_L_UINT16();
		mh->unknown5   = file->Read_L_UINT16();
		mh->patNum     = file->Read_L_UINT16();
		mh->insNum     = file->Read_L_UINT16();
		mh->ordNum     = file->Read_L_UINT16();
		mh->unknown6   = file->Read_L_UINT16();
		mh->unknown7   = file->Read_L_UINT16();
		mh->unknown8   = file->Read_L_UINT16();
		file->Read(mh->scrm, 4);

		if (file->IsEOF())
		{
			ShowError(IDS_MIKC_ERR_LOADING_HEADER);
			throw PUserException();
		}

		// Set module variables
		of.songName.SetString(mh->songName, &charSet850);
		of.numPat    = mh->patNum;
		of.repPos    = 0;
		of.numIns    = of.numSmp = mh->insNum;
		of.initSpeed = mh->initSpeed;
		of.initTempo = 125;
		of.numChn    = 4;
		of.flags    |= UF_S3MSLIDES;
		of.bpmLimit  = 32;

		if ((paraPtr = new uint16[of.numIns + of.numPat]) == NULL)
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		// Read the instrument + patterns parapointers
		file->Seek(mh->insPtr << 4, PFile::pSeekBegin);
		file->ReadArray_L_UINT16s(paraPtr, of.numIns);

		file->Seek(mh->patPtr << 4, PFile::pSeekBegin);
		file->ReadArray_L_UINT16s(paraPtr + of.numIns, of.numPat);

		// Check module version
		file->Seek(paraPtr[of.numIns] << 4, PFile::pSeekBegin);
		version = file->Read_L_UINT16();
		if (version == mh->patSize)
		{
			version = 0x10;
			convInfo->modKind.LoadString(res, IDS_MIKC_NAME_STX_10);
		}
		else
		{
			version = 0x11;
			convInfo->modKind.LoadString(res, IDS_MIKC_NAME_STX_11);
		}

		convInfo->fileType.LoadString(res, IDS_MIKC_MIME_STX);

		// Read the order data
		file->Seek((mh->chnPtr << 4) + 32, PFile::pSeekBegin);

		if (!(AllocPositions(mh->ordNum)))
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		for (t = 0; t < mh->ordNum; t++)
		{
			of.positions[t] = file->Read_UINT8();
			file->Seek(4, PFile::pSeekCurrent);
		}

		of.numPos    = 0;
		posLookupCnt = mh->ordNum;

		for (t = 0; t < mh->ordNum; t++)
		{
			int32 order = of.positions[t];
			if (order == 255)
				order = LAST_PATTERN;

			of.positions[of.numPos] = order;
			posLookup[t] = of.numPos;		// Bug fix for freaky S3Ms

			if (of.positions[t] < 254)
				of.numPos++;
			else
			{
				// Special end of song pattern
				if ((order == LAST_PATTERN) && (!curious))
					break;
			}
		}

		if (file->IsEOF())
		{
			ShowError(IDS_MIKC_ERR_LOADING_HEADER);
			throw PUserException();
		}

		// Load samples
		if (!(AllocSamples()))
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		for (q = of.samples, t = 0; t < of.numIns; t++, q++)
		{
			STXSAMPLE s;

			// Seek to instrument position
			file->Seek(((int32)paraPtr[t]) << 4, PFile::pSeekBegin);

			// And load sample info
			s.type = file->Read_UINT8();

			file->ReadString(s.fileName, 12);

			s.memSegH = file->Read_UINT8();
			s.memSegL = file->Read_L_UINT16();
			s.length  = file->Read_L_UINT32();
			s.loopBeg = file->Read_L_UINT32();
			s.loopEnd = file->Read_L_UINT32();
			s.volume  = file->Read_UINT8();
			s.dsk     = file->Read_UINT8();
			s.pack    = file->Read_UINT8();
			s.flags   = file->Read_UINT8();
			s.c2Spd   = file->Read_L_UINT32();

			file->Read(s.unused, 12);
			file->ReadString(s.sampName, 28);
			file->Read(s.scrs, 4);

			if (file->IsEOF())
			{
				ShowError(IDS_MIKC_ERR_LOADING_SAMPLEINFO);
				throw PUserException();
			}

			q->sampleName.SetString(s.sampName, &charSet850);
			q->speed      = (s.c2Spd * 8363) / 8448;
			q->length     = s.length;
			q->loopStart  = s.loopBeg;
			q->loopEnd    = s.loopEnd;
			q->volume     = s.volume;
			q->seekPos    = (((int32)s.memSegH) << 16 | s.memSegL) << 4;
			q->flags     |= SF_SIGNED;

			if (s.flags & 1)
				q->flags |= SF_LOOP;

			if (s.flags & 4)
				q->flags |= SF_16BITS;
		}

		// Load pattern info
		of.numTrk = of.numPat * of.numChn;

		if (!(AllocTracks()))
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		if (!(AllocPatterns()))
		{
			ShowError(IDS_MIKC_ERR_MEMORY);
			throw PUserException();
		}

		for (t = 0; t < of.numPat; t++)
		{
			// Seek to pattern position (+2 skip pattern length)
			file->Seek((((int32)paraPtr[of.numIns + t]) << 4) + (version == 0x10 ? 2 : 0), PFile::pSeekBegin);
			ReadPattern(file);

			for (u = 0; u < of.numChn; u++)
			{
				if (!(of.tracks[track++] = ConvertTrack(&stxBuf[u * 64])))
				{
					ShowError(IDS_MIKC_ERR_INITIALIZE);
					throw PUserException();
				}
			}
		}
	}
	catch(PUserException e)
	{
		retVal = AP_ERROR;
	}

	// Clean up again
	delete[] stxBuf;
	stxBuf = NULL;

	delete[] paraPtr;
	paraPtr = NULL;

	delete[] posLookup;
	posLookup = NULL;

	delete mh;
	mh = NULL;

	return (retVal);
}
Example #9
0
static BOOL UNI_Load(BOOL curious)
{
	int t;
	char *modtype,*oldtype=NULL;
	INSTRUMENT *d;
	SAMPLE *q;

	/* read module header */
	_mm_read_UBYTES(mh.id,4,modreader);
	if(mh.id[3]!='N')
		universion=mh.id[3]-'0';
	else
		universion=0x100;

	if(universion>=6) {
		if (universion==6) {
			_mm_skip_BYTE(modreader);
		} else {
			universion=_mm_read_M_UWORD(modreader);
		}
		mh.flags     =_mm_read_M_UWORD(modreader);
		mh.numchn    =_mm_read_UBYTE(modreader);
		mh.numvoices =_mm_read_UBYTE(modreader);
		mh.numpos    =_mm_read_M_UWORD(modreader);
		mh.numpat    =_mm_read_M_UWORD(modreader);
		mh.numtrk    =_mm_read_M_UWORD(modreader);
		mh.numins    =_mm_read_M_UWORD(modreader);
		mh.numsmp    =_mm_read_M_UWORD(modreader);
		mh.reppos    =_mm_read_M_UWORD(modreader);
		mh.initspeed =_mm_read_UBYTE(modreader);
		mh.inittempo =_mm_read_UBYTE(modreader);
		mh.initvolume=_mm_read_UBYTE(modreader);
		/* I expect this to show up soon in APlayer 1.06 format */
		if (universion >= 0x106)
			mh.bpmlimit=_mm_read_M_UWORD(modreader);
		else
			mh.bpmlimit=32;

		mh.flags &= UF_XMPERIODS | UF_LINEAR | UF_INST | UF_NNA;
		mh.flags |= UF_PANNING;
	} else {
		mh.numchn    =_mm_read_UBYTE(modreader);
		mh.numpos    =_mm_read_I_UWORD(modreader);
		mh.reppos    =(universion==5)?_mm_read_I_UWORD(modreader):0;
		mh.numpat    =_mm_read_I_UWORD(modreader);
		mh.numtrk    =_mm_read_I_UWORD(modreader);
		mh.numins    =_mm_read_I_UWORD(modreader);
		mh.initspeed =_mm_read_UBYTE(modreader);
		mh.inittempo =_mm_read_UBYTE(modreader);
		_mm_read_UBYTES(mh.positions,256,modreader);
		_mm_read_UBYTES(mh.panning,32,modreader);
		mh.flags     =_mm_read_UBYTE(modreader);
		mh.bpmlimit  =32;

		mh.flags &= UF_XMPERIODS | UF_LINEAR;
		mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING;
	}

	/* set module parameters */
	of.flags     =mh.flags;
	of.numchn    =mh.numchn;
	of.numpos    =mh.numpos;
	of.numpat    =mh.numpat;
	of.numtrk    =mh.numtrk;
	of.numins    =mh.numins;
	of.reppos    =mh.reppos;
	of.initspeed =mh.initspeed;
	of.inittempo =mh.inittempo;
	if(mh.bpmlimit)
		of.bpmlimit=mh.bpmlimit;
	else
		/* be bug-compatible with older releases */
		of.bpmlimit=32;

	of.songname=readstring();
	if(universion<0x102)
		oldtype=readstring();
	if(oldtype) {
		size_t len=strlen(oldtype)+20;
		if(!(modtype=(char*)MikMod_malloc(len))) return 0;
#ifdef HAVE_SNPRINTF
		snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
#else
		sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
#endif
	} else {
		if(!(modtype=(char*)MikMod_malloc(10))) return 0;
#ifdef HAVE_SNPRINTF
		snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
#else
		sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
#endif
	}
	of.modtype=MikMod_strdup(modtype);
	MikMod_free(modtype);MikMod_free(oldtype);
	of.comment=readstring();

	if(universion>=6) {
		of.numvoices=mh.numvoices;
		of.initvolume=mh.initvolume;
	}

	if(_mm_eof(modreader)) {
		_mm_errno=MMERR_LOADING_HEADER;
		return 0;
	}

	/* positions */
	if(!AllocPositions(of.numpos)) return 0;
	if(universion>=6) {
		if(universion>=0x100)
			_mm_read_M_UWORDS(of.positions,of.numpos,modreader);
		else
			for(t=0;t<of.numpos;t++) of.positions[t]=_mm_read_UBYTE(modreader);
		_mm_read_M_UWORDS(of.panning,of.numchn,modreader);
		_mm_read_UBYTES(of.chanvol,of.numchn,modreader);
	} else {
		if((mh.numpos>256)||(mh.numchn>32)) {
			_mm_errno=MMERR_LOADING_HEADER;
			return 0;
		}
		for(t=0;t<of.numpos;t++) of.positions[t]=mh.positions[t];
		for(t=0;t<of.numchn;t++) of.panning[t]=mh.panning[t];
	}
	/* convert the ``end of song'' pattern code if necessary */
	if(universion<0x106)
		for(t=0;t<of.numpos;t++)
			if(of.positions[t]==255) of.positions[t]=LAST_PATTERN;

	/* instruments and samples */
	if(universion>=6) {
		of.numsmp=mh.numsmp;
		if(!AllocSamples()) return 0;
		if(!loadsmp6()) return 0;

		if(of.flags&UF_INST) {
			if(!AllocInstruments()) return 0;
			if(!loadinstr6()) return 0;
		}
	} else {
		if(!AllocInstruments()) return 0;
		if(!loadinstr5()) return 0;
		if(!AllocSamples()) {
			MikMod_free(wh);wh=NULL;
			return 0;
		}
		if(!loadsmp5()) return 0;

		/* check if the original file had no instruments */
		if(of.numsmp==of.numins) {
			for(t=0,d=of.instruments;t<of.numins;t++,d++) {
				int u;

				if((d->volpts)||(d->panpts)||(d->globvol!=64)) break;
				for(u=0;u<96;u++)
					if((d->samplenumber[u]!=t)||(d->samplenote[u]!=u)) break;
				if(u!=96) break;
			}
			if(t==of.numins) {
				of.flags&=~UF_INST;
				of.flags&=~UF_NOWRAP;
				for(t=0,d=of.instruments,q=of.samples;t<of.numins;t++,d++,q++) {
					q->samplename=d->insname;
					d->insname=NULL;
				}
			}
		}
	}

	/* patterns */
	if(!AllocPatterns()) return 0;
	if(universion>=6) {
		_mm_read_M_UWORDS(of.pattrows,of.numpat,modreader);
		_mm_read_M_UWORDS(of.patterns,of.numpat*of.numchn,modreader);
	} else {
		_mm_read_I_UWORDS(of.pattrows,of.numpat,modreader);
		_mm_read_I_UWORDS(of.patterns,of.numpat*of.numchn,modreader);
	}

	/* tracks */
	if(!AllocTracks()) return 0;
	for(t=0;t<of.numtrk;t++)
		if(!(of.tracks[t]=readtrack())) {
			_mm_errno=MMERR_LOADING_TRACK;
			return 0;
		}

	return 1;
}
Example #10
0
static BOOL STX_Load(BOOL curious)
{
	int t,u,track = 0;
	int version = 0;
	SAMPLE *q;

	/* try to read module header */
	_mm_read_string(mh->songname,20,modreader);
	_mm_read_string(mh->trackername,8,modreader);
	mh->patsize     =_mm_read_I_UWORD(modreader);
	mh->unknown1    =_mm_read_I_UWORD(modreader);
	mh->patptr      =_mm_read_I_UWORD(modreader);
	mh->insptr      =_mm_read_I_UWORD(modreader);
	mh->chnptr      =_mm_read_I_UWORD(modreader);
	mh->unknown2    =_mm_read_I_UWORD(modreader);
	mh->unknown3    =_mm_read_I_UWORD(modreader);
	mh->mastermult  =_mm_read_UBYTE(modreader);
	mh->initspeed   =_mm_read_UBYTE(modreader)>>4;
	mh->unknown4    =_mm_read_I_UWORD(modreader);
	mh->unknown5    =_mm_read_I_UWORD(modreader);
	mh->patnum      =_mm_read_I_UWORD(modreader);
	mh->insnum      =_mm_read_I_UWORD(modreader);
	mh->ordnum      =_mm_read_I_UWORD(modreader);
	mh->unknown6    =_mm_read_I_UWORD(modreader);
	mh->unknown7    =_mm_read_I_UWORD(modreader);
	mh->unknown8    =_mm_read_I_UWORD(modreader);
	_mm_read_string(mh->scrm,4,modreader);

	if(_mm_eof(modreader)) {
		_mm_errno = MMERR_LOADING_HEADER;
		return 0;
	}

	/* set module variables */
	of.songname    = DupStr(mh->songname,20,1);
	of.numpat      = mh->patnum;
	of.reppos      = 0;
	of.numins      = of.numsmp = mh->insnum;
	of.initspeed   = mh->initspeed;
	of.inittempo   = 125;
	of.numchn      = 4;
	of.flags      |= UF_S3MSLIDES;
	of.bpmlimit    = 32;

	if(!(paraptr=(UWORD*)MikMod_malloc((of.numins+of.numpat)*sizeof(UWORD))))
		return 0;

	/* read the instrument+pattern parapointers */
	_mm_fseek(modreader,mh->insptr<<4,SEEK_SET);
	_mm_read_I_UWORDS(paraptr,of.numins,modreader);
	_mm_fseek(modreader,mh->patptr<<4,SEEK_SET);
	_mm_read_I_UWORDS(paraptr+of.numins,of.numpat,modreader);

	/* check module version */
	_mm_fseek(modreader,paraptr[of.numins]<<4,SEEK_SET);
	version=_mm_read_I_UWORD(modreader);
	if(version==mh->patsize) {
		version    = 0x10;
		of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.0)");
	} else {
		version    = 0x11;
		of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.1)");
	}

	/* read the order data */
	_mm_fseek(modreader,(mh->chnptr<<4)+32,SEEK_SET);
	if(!AllocPositions(mh->ordnum)) return 0;
	for(t=0;t<mh->ordnum;t++) {
		of.positions[t]=_mm_read_UBYTE(modreader);
		_mm_fseek(modreader,4,SEEK_CUR);
	}

	of.numpos=0;poslookupcnt=mh->ordnum;
	for(t=0;t<mh->ordnum;t++) {
		int order=of.positions[t];
		if(order==255) order=LAST_PATTERN;
		of.positions[of.numpos]=order;
		poslookup[t]=of.numpos;	/* bug fix for freaky S3Ms */
		if(of.positions[t]<254) of.numpos++;
		else
		  /* special end of song pattern */
		  if((order==LAST_PATTERN)&&(!curious)) break;
	}

	if(_mm_eof(modreader)) {
		_mm_errno = MMERR_LOADING_HEADER;
		return 0;
	}

	/* load samples */
	if(!AllocSamples()) return 0;
	for(q=of.samples,t=0;t<of.numins;t++,q++) {
		STXSAMPLE s;

		/* seek to instrument position */
		_mm_fseek(modreader,((long)paraptr[t])<<4,SEEK_SET);
		/* and load sample info */
		s.type      =_mm_read_UBYTE(modreader);
		_mm_read_string(s.filename,12,modreader);
		s.memsegh   =_mm_read_UBYTE(modreader);
		s.memsegl   =_mm_read_I_UWORD(modreader);
		s.length    =_mm_read_I_ULONG(modreader);
		s.loopbeg   =_mm_read_I_ULONG(modreader);
		s.loopend   =_mm_read_I_ULONG(modreader);
		s.volume    =_mm_read_UBYTE(modreader);
		s.dsk       =_mm_read_UBYTE(modreader);
		s.pack      =_mm_read_UBYTE(modreader);
		s.flags     =_mm_read_UBYTE(modreader);
		s.c2spd     =_mm_read_I_ULONG(modreader);
		_mm_read_UBYTES(s.unused,12,modreader);
		_mm_read_string(s.sampname,28,modreader);
		_mm_read_string(s.scrs,4,modreader);

		if(_mm_eof(modreader)) {
			_mm_errno = MMERR_LOADING_SAMPLEINFO;
			return 0;
		}

		q->samplename = DupStr(s.sampname,28,1);
		q->speed      = (s.c2spd * 8363) / 8448;
		q->length     = s.length;
		q->loopstart  = s.loopbeg;
		q->loopend    = s.loopend;
		q->volume     = s.volume;
		q->seekpos    = (((long)s.memsegh)<<16|s.memsegl)<<4;
		q->flags     |= SF_SIGNED;

		if(s.flags&1) q->flags |= SF_LOOP;
		if(s.flags&4) q->flags |= SF_16BITS;
	}

	/* load pattern info */
	of.numtrk=of.numpat*of.numchn;
	if(!AllocTracks()) return 0;
	if(!AllocPatterns()) return 0;

	for(t=0;t<of.numpat;t++) {
		/* seek to pattern position (+2 skip pattern length) */
		_mm_fseek(modreader,(((long)paraptr[of.numins+t])<<4)+
			(version==0x10?2:0),SEEK_SET);
		if(!STX_ReadPattern()) return 0;
		for(u=0;u<of.numchn;u++)
			if(!(of.tracks[track++]=STX_ConvertTrack(&stxbuf[u*64]))) return 0;
	}

	return 1;
}