⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 5 页
字号:
	{			/* set reppos or repcnt ? */	  /* set repcnt, so check if repcnt already is set, which means we	     are already looping */	  if (a->pat_repcnt)	    a->pat_repcnt--;	/* already looping, decrease counter */	  else	    {#if 0	      /* this would make walker.xm, shipped with Xsoundtracker,	         play correctly, but it's better to remain compatible	         with FT2 */	      if ((!(pf->flags & UF_NOWRAP)) || (a->pat_reppos != POS_NONE))#endif		a->pat_repcnt = nib;	/* not yet looping, so set repcnt */	    }	  if (a->pat_repcnt)	    {			/* jump to reppos if repcnt>0 */	      if (a->pat_reppos == POS_NONE)		a->pat_reppos = mp.patpos - 1;	      if (a->pat_reppos == -1)		{		  mp.pat_repcrazy = 1;		  mp.patpos = 0;		}	      else		mp.patpos = a->pat_reppos;	    }	  else	    a->pat_reppos = POS_NONE;	}      else	a->pat_reppos = mp.patpos - 1;	/* set reppos - can be (-1) */      break;    case 0x7:			/* set tremolo waveform */      a->wavecontrol &= 0x0f;      a->wavecontrol |= nib << 4;      break;    case 0x8:			/* set panning */      if (nib <= 8)	nib <<= 4;      else	nib *= 17;      a->panning = pf->panning[mp.channel] = nib;      break;    case 0x9:			/* retrig note */      /* only retrigger if data nibble > 0 */      if (nib)	{	  if (!a->retrig)	    {	      /* when retrig counter reaches 0, reset counter and restart	         the sample */	      if (a->period)		a->kick = KICK_NOTE;	      a->retrig = nib;	    }	  a->retrig--;		/* countdown */	}      break;    case 0xa:			/* fine volume slide up */      if (mp.vbtick)	break;      a->tmpvolume += nib;      if (a->tmpvolume > 64)	a->tmpvolume = 64;      break;    case 0xb:			/* fine volume slide dn  */      if (mp.vbtick)	break;      a->tmpvolume -= nib;      if (a->tmpvolume < 0)	a->tmpvolume = 0;      break;    case 0xc:			/* cut note */      /* When mp.vbtick reaches the cut-note value, turn the volume to         zero ( Just like on the amiga) */      if (mp.vbtick >= nib)	a->tmpvolume = 0;	/* just turn the volume down */      break;    case 0xd:			/* note delay */      /* delay the start of the sample until mp.vbtick==nib */      if (!mp.vbtick)	a->notedelay = nib;      else if (a->notedelay)	a->notedelay--;      break;    case 0xe:			/* pattern delay */      if (mp.vbtick)	break;      if (!mp.patdly2)	mp.patdly = nib + 1;	/* only once, when vbtick=0 */      break;    case 0xf:			/* invert loop, not supported  */      break;    }}static void DoVibrato (void){  UBYTE q;  UWORD temp = 0;  q = (a->vibpos >> 2) & 0x1f;  switch (a->wavecontrol & 3)    {    case 0:			/* sine */      temp = VibratoTable[q];      break;    case 1:			/* ramp down */      q <<= 3;      if (a->vibpos < 0)	q = 255 - q;      temp = q;      break;    case 2:			/* square wave */      temp = 255;      break;    case 3:			/* random wave */      temp = getrandom (256);      break;    }  temp *= a->vibdepth;  temp >>= 7;  temp <<= 2;  if (a->vibpos >= 0)    a->period = a->tmpperiod + temp;  else    a->period = a->tmpperiod - temp;  if (mp.vbtick)    a->vibpos += a->vibspd;}static void DoTremolo (void){  UBYTE q;  UWORD temp = 0;  q = (a->trmpos >> 2) & 0x1f;  switch ((a->wavecontrol >> 4) & 3)    {    case 0:			/* sine */      temp = VibratoTable[q];      break;    case 1:			/* ramp down */      q <<= 3;      if (a->trmpos < 0)	q = 255 - q;      temp = q;      break;    case 2:			/* square wave */      temp = 255;      break;    case 3:			/* random wave */      temp = getrandom (256);      break;    }  temp *= a->trmdepth;  temp >>= 6;  if (a->trmpos >= 0)    {      a->volume = a->tmpvolume + temp;      if (a->volume > 64)	a->volume = 64;    }  else    {      a->volume = a->tmpvolume - temp;      if (a->volume < 0)	a->volume = 0;    }  if (mp.vbtick)    a->trmpos += a->trmspd;}static void DoVolSlide (UBYTE dat){  if (!mp.vbtick)    return;  if (dat & 0xf)    {      a->tmpvolume -= (dat & 0x0f);      if (a->tmpvolume < 0)	a->tmpvolume = 0;    }  else    {      a->tmpvolume += (dat >> 4);      if (a->tmpvolume > 64)	a->tmpvolume = 64;    }}static void DoToneSlide (void){  if (mp.vbtick)    {      int dist;      /* We have to slide a->period towards a->wantedperiod, so compute the         difference between those two values */      dist = a->period - a->wantedperiod;      /* if they are equal or if portamentospeed is too big ... */      if ((!dist) || a->portspeed > abs (dist))	/* ...make tmpperiod equal tperiod */	a->tmpperiod = a->period = a->wantedperiod;      else if (dist > 0)	{	  a->tmpperiod -= a->portspeed;	  a->period -= a->portspeed;	/* dist>0, slide up */	}      else	{	  a->tmpperiod += a->portspeed;	  a->period += a->portspeed;	/* dist<0, slide down */	}    }  else    a->tmpperiod = a->period;}static void DoArpeggio (UBYTE dat){  UBYTE note = a->note;  if (dat)    {      switch (mp.vbtick % 3)	{	case 1:	  note += (dat >> 4);	  break;	case 2:	  note += (dat & 0xf);	  break;	}      a->period = GetPeriod ((UWORD) note << 1, a->speed);      a->ownper = 1;    }}/*========== Scream Tracker effects */static void DoS3MVolSlide (UBYTE inf){  UBYTE lo, hi;  if (inf)    a->s3mvolslide = inf;  else    inf = a->s3mvolslide;  lo = inf & 0xf;  hi = inf >> 4;  if (!lo)    {      if ((mp.vbtick) || (pf->flags & UF_S3MSLIDES))	a->tmpvolume += hi;    }  else if (!hi)    {      if ((mp.vbtick) || (pf->flags & UF_S3MSLIDES))	a->tmpvolume -= lo;    }  else if (lo == 0xf)    {      if (!mp.vbtick)	a->tmpvolume += (hi ? hi : 0xf);    }  else if (hi == 0xf)    {      if (!mp.vbtick)	a->tmpvolume -= (lo ? lo : 0xf);    }  else    return;  if (a->tmpvolume < 0)    a->tmpvolume = 0;  else if (a->tmpvolume > 64)    a->tmpvolume = 64;}static void DoS3MSlideDn (UBYTE inf){  UBYTE hi, lo;  if (inf)    a->slidespeed = inf;  else    inf = a->slidespeed;  hi = inf >> 4;  lo = inf & 0xf;  if (hi == 0xf)    {      if (!mp.vbtick)	a->tmpperiod += (UWORD) lo << 2;    }  else if (hi == 0xe)    {      if (!mp.vbtick)	a->tmpperiod += lo;    }  else    {      if (mp.vbtick)	a->tmpperiod += (UWORD) inf << 2;    }}static void DoS3MSlideUp (UBYTE inf){  UBYTE hi, lo;  if (inf)    a->slidespeed = inf;  else    inf = a->slidespeed;  hi = inf >> 4;  lo = inf & 0xf;  if (hi == 0xf)    {      if (!mp.vbtick)	a->tmpperiod -= (UWORD) lo << 2;    }  else if (hi == 0xe)    {      if (!mp.vbtick)	a->tmpperiod -= lo;    }  else    {      if (mp.vbtick)	a->tmpperiod -= (UWORD) inf << 2;    }}static void DoS3MTremor (UBYTE inf){  UBYTE on, off;  if (inf)    a->s3mtronof = inf;  else    {      inf = a->s3mtronof;      if (!inf)	return;    }  if (!mp.vbtick)    return;  on = (inf >> 4) + 1;  off = (inf & 0xf) + 1;  a->s3mtremor %= (on + off);  a->volume = (a->s3mtremor < on) ? a->tmpvolume : 0;  a->s3mtremor++;}static void DoS3MRetrig (UBYTE inf){  if (inf)    {      a->s3mrtgslide = inf >> 4;      a->s3mrtgspeed = inf & 0xf;    }  /* only retrigger if low nibble > 0 */  if (a->s3mrtgspeed > 0)    {      if (!a->retrig)	{	  /* when retrig counter reaches 0, reset counter and restart the	     sample */	  if (a->kick != KICK_NOTE)	    a->kick = KICK_KEYOFF;	  a->retrig = a->s3mrtgspeed;	  if ((mp.vbtick) || (pf->flags & UF_S3MSLIDES))	    {	      switch (a->s3mrtgslide)		{		case 1:		case 2:		case 3:		case 4:		case 5:		  a->tmpvolume -= (1 << (a->s3mrtgslide - 1));		  break;		case 6:		  a->tmpvolume = (2 * a->tmpvolume) / 3;		  break;		case 7:		  a->tmpvolume >>= 1;		  break;		case 9:		case 0xa:		case 0xb:		case 0xc:		case 0xd:		  a->tmpvolume += (1 << (a->s3mrtgslide - 9));		  break;		case 0xe:		  a->tmpvolume = (3 * a->tmpvolume) >> 1;		  break;		case 0xf:		  a->tmpvolume = a->tmpvolume << 1;		  break;		}	      if (a->tmpvolume < 0)		a->tmpvolume = 0;	      else if (a->tmpvolume > 64)		a->tmpvolume = 64;	    }	}      a->retrig--;		/* countdown  */    }}static void DoS3MSpeed (UBYTE speed){  if (mp.vbtick || mp.patdly2)    return;  if (speed > 128)    speed -= 128;  if (speed)    {      mp.sngspd = speed;      mp.vbtick = 0;    }}static void DoS3MTempo (UBYTE tempo){  if (mp.vbtick || mp.patdly2)    return;  mp.newbpm = (tempo < 32) ? 32 : tempo;}static void DoS3MFineVibrato (void){  UBYTE q;  UWORD temp = 0;  q = (a->vibpos >> 2) & 0x1f;  switch (a->wavecontrol & 3)    {    case 0:			/* sine */      temp = VibratoTable[q];      break;    case 1:			/* ramp down */      q <<= 3;      if (a->vibpos < 0)	q = 255 - q;      temp = q;      break;    case 2:			/* square wave */      temp = 255;      break;    case 3:			/* random */      temp = getrandom (256);      break;    }  temp *= a->vibdepth;  temp >>= 8;  if (a->vibpos >= 0)    a->period = a->tmpperiod + temp;  else    a->period = a->tmpperiod - temp;  a->vibpos += a->vibspd;}static void DoS3MTremolo (void){  UBYTE q;  UWORD temp = 0;  q = (a->trmpos >> 2) & 0x1f;  switch ((a->wavecontrol >> 4) & 3)    {    case 0:			/* sine */      temp = VibratoTable[q];      break;    case 1:			/* ramp down */      q <<= 3;      if (a->trmpos < 0)	q = 255 - q;      temp = q;      break;    case 2:			/* square wave */      temp = 255;      break;    case 3:			/* random */      temp = getrandom (256);      break;    }  temp *= a->trmdepth;  temp >>= 7;  if (a->trmpos >= 0)    {      a->volume = a->tmpvolume + temp;      if (a->volume > 64)	a->volume = 64;    }  else    {      a->volume = a->tmpvolume - temp;      if (a->volume < 0)	a->volume = 0;    }  if (mp.vbtick)    a->trmpos += a->trmspd;}/*========== Fast Tracker effects */static void DoXMVolSlide (UBYTE inf){  UBYTE lo, hi;  mp.explicitslides = 2;  if (inf)    a->s3mvolslide = inf;  else    inf = a->s3mvolslide;  if (!mp.vbtick)    return;  lo = inf & 0xf;  hi = inf >> 4;  if (!hi)    {      a->tmpvolume -= lo;      if (a->tmpvolume < 0)	a->tmpvolume = 0;    }  else    {      a->tmpvolume += hi;      if (a->tmpvolume > 64)	a->tmpvolume = 64;    }}static void 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -