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

📄 load_669.c

📁 MIDI解码程序(用VC编写)
💻 C
字号:
/*      MikMod sound library   (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for   complete list.   This library is free software; you can redistribute it and/or modify   it under the terms of the GNU Library General Public License as   published by the Free Software Foundation; either version 2 of   the License, or (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with this library; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA   02111-1307, USA. *//*==============================================================================  $Id: load_669.c,v 1.30 1999/10/25 16:31:41 miod Exp $  Composer 669 module loader==============================================================================*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "unimod_priv.h"/*========== Module structure *//* header */typedef struct S69HEADER  {    UBYTE marker[2];    CHAR message[108];    UBYTE nos;    UBYTE nop;    UBYTE looporder;    UBYTE orders[0x80];    UBYTE tempos[0x80];    UBYTE breaks[0x80];  }S69HEADER;/* sample information */typedef struct S69SAMPLE  {    CHAR filename[13];    SLONG length;    SLONG loopbeg;    SLONG loopend;  }S69SAMPLE;/* encoded note */typedef struct S69NOTE  {    UBYTE a, b, c;  }S69NOTE;/*========== Loader variables *//* current pattern */static S69NOTE *s69pat = NULL;/* Module header */static S69HEADER *mh = NULL;/* file type identification */static CHAR *S69_Version[] ={  "Composer 669",  "Extended 669"};/*========== Loader code */BOOL S69_Test (void){  UBYTE buf[0x80];  if (!_mm_read_UBYTES (buf, 2, modreader))    return 0;  /* look for id */  if (!memcmp (buf, "if", 2) || !memcmp (buf, "JN", 2))    {      int i;      /* skip song message */      _mm_fseek (modreader, 108, SEEK_CUR);      /* sanity checks */      if (_mm_read_UBYTE (modreader) > 64)	return 0;      if (_mm_read_UBYTE (modreader) > 128)	return 0;      if (_mm_read_UBYTE (modreader) > 127)	return 0;      /* check order table */      if (!_mm_read_UBYTES (buf, 0x80, modreader))	return 0;      for (i = 0; i < 0x80; i++)	if ((buf[i] >= 0x80) && (buf[i] != 0xff))	  return 0;      /* check tempos table */      if (!_mm_read_UBYTES (buf, 0x80, modreader))	return 0;      for (i = 0; i < 0x80; i++)	if ((!buf[i]) || (buf[i] > 32))	  return 0;      /* check pattern length table */      if (!_mm_read_UBYTES (buf, 0x80, modreader))	return 0;      for (i = 0; i < 0x80; i++)	if (buf[i] > 0x3f)	  return 0;    }  else    return 0;  return 1;}BOOL S69_Init (void){  if (!(s69pat = (S69NOTE *) _mm_malloc (64 * 8 * sizeof (S69NOTE))))    return 0;  if (!(mh = (S69HEADER *) _mm_malloc (sizeof (S69HEADER))))    return 0;  return 1;}void S69_Cleanup (void){  _mm_free (s69pat);  _mm_free (mh);}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;}BOOL S69_Load (BOOL curious){  int i;  SAMPLE *current;  S69SAMPLE sample;  /* module header */  _mm_read_UBYTES (mh->marker, 2, modreader);  _mm_read_UBYTES (mh->message, 108, modreader);  mh->nos = _mm_read_UBYTE (modreader);  mh->nop = _mm_read_UBYTE (modreader);  mh->looporder = _mm_read_UBYTE (modreader);  _mm_read_UBYTES (mh->orders, 0x80, modreader);  for (i = 0; i < 0x80; i++)    if ((mh->orders[i] >= 0x80) && (mh->orders[i] != 0xff))      {	_mm_errno = MMERR_NOT_A_MODULE;	return 1;      }  _mm_read_UBYTES (mh->tempos, 0x80, modreader);  for (i = 0; i < 0x80; i++)    if ((!mh->tempos[i]) || (mh->tempos[i] > 32))      {	_mm_errno = MMERR_NOT_A_MODULE;	return 1;      }  _mm_read_UBYTES (mh->breaks, 0x80, modreader);  for (i = 0; i < 0x80; i++)    if (mh->breaks[i] > 0x3f)      {	_mm_errno = MMERR_NOT_A_MODULE;	return 1;      }  /* set module variables */  of.initspeed = 4;  of.inittempo = 78;  of.songname = DupStr (mh->message, 36, 1);  of.modtype = strdup (S69_Version[memcmp (mh->marker, "JN", 2) == 0]);  of.numchn = 8;  of.numpat = mh->nop;  of.numins = of.numsmp = mh->nos;  of.numtrk = of.numchn * of.numpat;  of.flags = UF_XMPERIODS | UF_LINEAR;  for (i = 35; (i >= 0) && (mh->message[i] == ' '); i--)    mh->message[i] = 0;  for (i = 36 + 35; (i >= 36 + 0) && (mh->message[i] == ' '); i--)    mh->message[i] = 0;  for (i = 72 + 35; (i >= 72 + 0) && (mh->message[i] == ' '); i--)    mh->message[i] = 0;  if ((mh->message[0]) || (mh->message[36]) || (mh->message[72]))    if ((of.comment = (CHAR *) _mm_malloc (3 * (36 + 1) + 1)))      {	strncpy (of.comment, mh->message, 36);	strcat (of.comment, "\r");	if (mh->message[36])	  strncat (of.comment, mh->message + 36, 36);	strcat (of.comment, "\r");	if (mh->message[72])	  strncat (of.comment, mh->message + 72, 36);	strcat (of.comment, "\r");	of.comment[3 * (36 + 1)] = 0;      }  if (!AllocPositions (0x80))    return 0;  for (i = 0; i < 0x80; i++)    {      if (mh->orders[i] >= mh->nop)	break;      of.positions[i] = mh->orders[i];    }  of.numpos = i;  of.reppos = mh->looporder < of.numpos ? mh->looporder : 0;  if (!AllocSamples ())    return 0;  current = of.samples;  for (i = 0; i < of.numins; i++)    {      /* sample information */      _mm_read_UBYTES ((UBYTE *) sample.filename, 13, modreader);      sample.length = _mm_read_I_SLONG (modreader);      sample.loopbeg = _mm_read_I_SLONG (modreader);      sample.loopend = _mm_read_I_SLONG (modreader);      if (sample.loopend == 0xfffff)	sample.loopend = 0;      if ((sample.length < 0) || (sample.loopbeg < -1) || (sample.loopend < -1))	{	  _mm_errno = MMERR_LOADING_HEADER;	  return 0;	}      current->samplename = DupStr (sample.filename, 13, 1);      current->seekpos = 0;      current->speed = 0;      current->length = sample.length;      current->loopstart = sample.loopbeg;      current->loopend = (sample.loopend < sample.length) ? sample.loopend : sample.length;      current->flags = (sample.loopbeg < sample.loopend) ? SF_LOOP : 0;      current->volume = 64;      current++;    }  if (!S69_LoadPatterns ())    return 0;  return 1;}CHAR *S69_LoadTitle (void){  CHAR s[36];  _mm_fseek (modreader, 2, SEEK_SET);  if (!_mm_read_UBYTES (s, 36, modreader))    return NULL;  return (DupStr (s, 36, 1));}/*========== Loader information */MLOADER load_669 ={  NULL,  "669",  "669 (Composer 669, Unis 669)",  S69_Init,  S69_Test,  S69_Load,  S69_Cleanup,  S69_LoadTitle};/* ex:set ts=4: */

⌨️ 快捷键说明

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