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

📄 load_xm.c

📁 SDL_mixer 是一个基于 SDL 的混音器
💻 C
📖 第 1 页 / 共 2 页
字号:
			}			for(v=0;v<of.numchn;v++)				of.tracks[numtrk++]=XM_Convert(&xmpat[v*ph.numrows],ph.numrows);			free(xmpat);xmpat=NULL;		} else {			for(v=0;v<of.numchn;v++)				of.tracks[numtrk++]=XM_Convert(NULL,ph.numrows);		}	}	if(dummypat) {		of.pattrows[t]=64;		if(!(xmpat=(XMNOTE*)_mm_calloc(64*of.numchn,sizeof(XMNOTE)))) return 0;		for(v=0;v<of.numchn;v++)			of.tracks[numtrk++]=XM_Convert(&xmpat[v*64],64);		free(xmpat);xmpat=NULL;	}	return 1;}static BOOL LoadInstruments(void){	int t,u;	INSTRUMENT *d;	ULONG next=0;	UWORD wavcnt=0;	if(!AllocInstruments()) return 0;	d=of.instruments;	for(t=0;t<of.numins;t++,d++) {		XMINSTHEADER ih;		long headend;		memset(d->samplenumber,0xff,INSTNOTES*sizeof(UWORD));		/* read instrument header */		headend     = _mm_ftell(modreader);		ih.size     = _mm_read_I_ULONG(modreader);		headend    += ih.size;		_mm_read_string(ih.name, 22, modreader);		ih.type     = _mm_read_UBYTE(modreader);		ih.numsmp   = _mm_read_I_UWORD(modreader);		d->insname  = DupStr(ih.name,22,1);		if((SWORD)ih.size>29) {			ih.ssize    = _mm_read_I_ULONG(modreader);			if(((SWORD)ih.numsmp>0)&&(ih.numsmp<=XMNOTECNT)) {				XMPATCHHEADER pth;				int p;				_mm_read_UBYTES (pth.what,XMNOTECNT,modreader);				_mm_read_I_UWORDS (pth.volenv, XMENVCNT, modreader);				_mm_read_I_UWORDS (pth.panenv, XMENVCNT, modreader);				pth.volpts      =  _mm_read_UBYTE(modreader);				pth.panpts      =  _mm_read_UBYTE(modreader);				pth.volsus      =  _mm_read_UBYTE(modreader);				pth.volbeg      =  _mm_read_UBYTE(modreader);				pth.volend      =  _mm_read_UBYTE(modreader);				pth.pansus      =  _mm_read_UBYTE(modreader);				pth.panbeg      =  _mm_read_UBYTE(modreader);				pth.panend      =  _mm_read_UBYTE(modreader);				pth.volflg      =  _mm_read_UBYTE(modreader);				pth.panflg      =  _mm_read_UBYTE(modreader);				pth.vibflg      =  _mm_read_UBYTE(modreader);				pth.vibsweep    =  _mm_read_UBYTE(modreader);				pth.vibdepth    =  _mm_read_UBYTE(modreader);				pth.vibrate     =  _mm_read_UBYTE(modreader);				pth.volfade     =  _mm_read_I_UWORD(modreader);				/* read the remainder of the header				   (2 bytes for 1.03, 22 for 1.04) */				for(u=headend-_mm_ftell(modreader);u;u--) _mm_read_UBYTE(modreader);				/* we can't trust the envelope point count here, as some				   modules have incorrect values (K_OSPACE.XM reports 32 volume				   points, for example). */				if(pth.volpts>XMENVCNT/2) pth.volpts=XMENVCNT/2;				if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2;				if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) {					if(nextwav) { free(nextwav);nextwav=NULL; }					if(wh) { free(wh);wh=NULL; }					_mm_errno = MMERR_LOADING_SAMPLEINFO;					return 0;				}				for(u=0;u<XMNOTECNT;u++)					d->samplenumber[u]=pth.what[u]+of.numsmp;				d->volfade = pth.volfade;memcpy(d->volenv,pth.volenv,XMENVCNT);if (pth.volflg&1) d->volflg|=EF_ON;if (pth.volflg&2) d->volflg|=EF_SUSTAIN;if (pth.volflg&4) d->volflg|=EF_LOOP;d->volsusbeg=d->volsusend=pth.volsus;                                      d->volbeg=pth.volbeg;d->volend=pth.volend;d->volpts=pth.volpts;/* scale envelope */for (p=0;p<XMENVCNT/2;p++)                                                        d->volenv[p].val<<=2;if ((d->volflg&EF_ON)&&(d->volpts<2)) d->volflg&=~EF_ON;memcpy(d->panenv,pth.panenv,XMENVCNT);if (pth.panflg&1) d->panflg|=EF_ON;if (pth.panflg&2) d->panflg|=EF_SUSTAIN;if (pth.panflg&4) d->panflg|=EF_LOOP;d->pansusbeg=d->pansusend=pth.pansus;                                      d->panbeg=pth.panbeg;d->panend=pth.panend;d->panpts=pth.panpts;/* scale envelope */for (p=0;p<XMENVCNT/2;p++)                                                        d->panenv[p].val<<=2;if ((d->panflg&EF_ON)&&(d->panpts<2)) d->panflg&=~EF_ON;				/* Samples are stored outside the instrument struct now, so we				   have to load them all into a temp area, count the of.numsmp				   along the way and then do an AllocSamples() and move				   everything over */				if(mh->version>0x0103) next = 0;				for(u=0;u<ih.numsmp;u++,s++) {					/* Allocate more room for sample information if necessary */					if(of.numsmp+u==wavcnt) {						wavcnt+=XM_SMPINCR;						if(!(nextwav=realloc(nextwav,wavcnt*sizeof(ULONG)))){							if(wh) { free(wh);wh=NULL; }							_mm_errno = MMERR_OUT_OF_MEMORY;							return 0;						}						if(!(wh=realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {							free(nextwav);nextwav=NULL;							_mm_errno = MMERR_OUT_OF_MEMORY;							return 0;						}						s=wh+(wavcnt-XM_SMPINCR);					}					s->length       =_mm_read_I_ULONG (modreader);					s->loopstart    =_mm_read_I_ULONG (modreader);					s->looplength   =_mm_read_I_ULONG (modreader);					s->volume       =_mm_read_UBYTE (modreader);					s->finetune     =_mm_read_SBYTE (modreader);					s->type         =_mm_read_UBYTE (modreader);					s->panning      =_mm_read_UBYTE (modreader);					s->relnote      =_mm_read_SBYTE (modreader);					s->vibtype      = pth.vibflg;					s->vibsweep     = pth.vibsweep;					s->vibdepth     = pth.vibdepth*4;					s->vibrate      = pth.vibrate;					s->reserved     =_mm_read_UBYTE (modreader);					_mm_read_string(s->samplename, 22, modreader);					nextwav[of.numsmp+u]=next;					next+=s->length;					if(_mm_eof(modreader)) {						free(nextwav);free(wh);						nextwav=NULL;wh=NULL;						_mm_errno = MMERR_LOADING_SAMPLEINFO;						return 0;					}				}				if(mh->version>0x0103) {					for(u=0;u<ih.numsmp;u++)						nextwav[of.numsmp++]+=_mm_ftell(modreader);					_mm_fseek(modreader,next,SEEK_CUR);				} else					of.numsmp+=ih.numsmp;			} else {				/* read the remainder of the header */				for(u=headend-_mm_ftell(modreader);u;u--) _mm_read_UBYTE(modreader);				if(_mm_eof(modreader)) {					free(nextwav);free(wh);					nextwav=NULL;wh=NULL;					_mm_errno = MMERR_LOADING_SAMPLEINFO;					return 0;				}			}		}	}	/* sanity check */	if(!of.numsmp) {		if(nextwav) { free(nextwav);nextwav=NULL; }		if(wh) { free(wh);wh=NULL; }		_mm_errno = MMERR_LOADING_SAMPLEINFO;		return 0;	}	return 1;}BOOL XM_Load(BOOL curious){	INSTRUMENT *d;	SAMPLE *q;	int t,u;	BOOL dummypat=0;	char tracker[21],modtype[60];	/* try to read module header */	_mm_read_string(mh->id,17,modreader);	_mm_read_string(mh->songname,21,modreader);	_mm_read_string(mh->trackername,20,modreader);	mh->version     =_mm_read_I_UWORD(modreader);	if((mh->version<0x102)||(mh->version>0x104)) {		_mm_errno=MMERR_NOT_A_MODULE;		return 0;	}	mh->headersize  =_mm_read_I_ULONG(modreader);	mh->songlength  =_mm_read_I_UWORD(modreader);	mh->restart     =_mm_read_I_UWORD(modreader);	mh->numchn      =_mm_read_I_UWORD(modreader);	mh->numpat      =_mm_read_I_UWORD(modreader);	mh->numins      =_mm_read_I_UWORD(modreader);	mh->flags       =_mm_read_I_UWORD(modreader);	mh->tempo       =_mm_read_I_UWORD(modreader);	mh->bpm         =_mm_read_I_UWORD(modreader);	if(!mh->bpm) {		_mm_errno=MMERR_NOT_A_MODULE;		return 0;	}	_mm_read_UBYTES(mh->orders,256,modreader);	if(_mm_eof(modreader)) {		_mm_errno = MMERR_LOADING_HEADER;		return 0;	}	/* set module variables */	of.initspeed = (UBYTE)mh->tempo;	of.inittempo = (UBYTE)mh->bpm;	strncpy(tracker,mh->trackername,20);tracker[20]=0;	for(t=20;(tracker[t]<=' ')&&(t>=0);t--) tracker[t]=0;	/* some modules have the tracker name empty */	if (!tracker[0])		strcpy(tracker,"Unknown tracker");#ifdef HAVE_SNPRINTF	snprintf(modtype,60,"%s (XM format %d.%02d)",	                    tracker,mh->version>>8,mh->version&0xff);#else	sprintf(modtype,"%s (XM format %d.%02d)",	                tracker,mh->version>>8,mh->version&0xff);#endif	of.modtype   = strdup(modtype);	of.numchn    = mh->numchn;	of.numpat    = mh->numpat;	of.numtrk    = (UWORD)of.numpat*of.numchn;   /* get number of channels */	of.songname  = DupStr(mh->songname,20,1);	of.numpos    = mh->songlength;               /* copy the songlength */	of.reppos    = mh->restart<mh->songlength?mh->restart:0;	of.numins    = mh->numins;	of.flags    |= UF_XMPERIODS|UF_INST|UF_NOWRAP|UF_FT2QUIRKS;	if(mh->flags&1) of.flags |= UF_LINEAR;	memset(of.chanvol,64,of.numchn);             /* store channel volumes */	if(!AllocPositions(of.numpos+1)) return 0;	for(t=0;t<of.numpos;t++)		of.positions[t]=mh->orders[t];	/* We have to check for any pattern numbers in the order list greater than	   the number of patterns total. If one or more is found, we set it equal to	   the pattern total and make a dummy pattern to workaround the problem */	for(t=0;t<of.numpos;t++) {		if(of.positions[t]>=of.numpat) {			of.positions[t]=of.numpat;			dummypat=1;		}	}	if(dummypat) {		of.numpat++;of.numtrk+=of.numchn;	}	if(mh->version<0x0104) {		if(!LoadInstruments()) return 0;		if(!LoadPatterns(dummypat)) return 0;		for(t=0;t<of.numsmp;t++)			nextwav[t]+=_mm_ftell(modreader);	} else {		if(!LoadPatterns(dummypat)) return 0;		if(!LoadInstruments()) return 0;	}	if(!AllocSamples()) {		free(nextwav);free(wh);		nextwav=NULL;wh=NULL;		return 0;	}	q = of.samples;	s = wh;	for(u=0;u<of.numsmp;u++,q++,s++) {		q->samplename   = DupStr(s->samplename,22,1);		q->length       = s->length;		q->loopstart    = s->loopstart;		q->loopend      = s->loopstart+s->looplength;		q->volume       = s->volume;		q->speed        = s->finetune+128;		q->panning      = s->panning;		q->seekpos      = nextwav[u];		q->vibtype      = s->vibtype;		q->vibsweep     = s->vibsweep;		q->vibdepth     = s->vibdepth;		q->vibrate      = s->vibrate;		if(s->type & 0x10) {			q->length    >>= 1;			q->loopstart >>= 1;			q->loopend   >>= 1;		}		q->flags|=SF_OWNPAN;		if(s->type&0x3) q->flags|=SF_LOOP;		if(s->type&0x2) q->flags|=SF_BIDI;		if(s->type&0x10) q->flags|=SF_16BITS;		q->flags|=SF_DELTA|SF_SIGNED;	}	d=of.instruments;	s=wh;	for(u=0;u<of.numins;u++,d++)		for(t=0;t<XMNOTECNT;t++) {			if (d->samplenumber[t]>=of.numsmp)				d->samplenote[t]=255;			else {				int note=t+s[d->samplenumber[t]].relnote;				d->samplenote[t]=(note<0)?0:note;			}		}	free(wh);free(nextwav);	wh=NULL;nextwav=NULL;	return 1;}CHAR *XM_LoadTitle(void){	CHAR s[21];	_mm_fseek(modreader,17,SEEK_SET);	if(!_mm_read_UBYTES(s,21,modreader)) return NULL;	return(DupStr(s,21,1));}/*========== Loader information */MIKMODAPI MLOADER load_xm={	NULL,	"XM",	"XM (FastTracker 2)",	XM_Init,	XM_Test,	XM_Load,	XM_Cleanup,	XM_LoadTitle};/* ex:set ts=4: */

⌨️ 快捷键说明

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