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

📄 load_xm.c

📁 wince下著名的视频播放器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	MikMod sound library	(c) 1998, 1999, 2000, 2001, 2002 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_xm.c,v 1.2 2004/02/06 19:29:03 raph Exp $  Fasttracker (XM) module loader==============================================================================*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <stdio.h>#ifdef HAVE_MEMORY_H#include <memory.h>#endif#include <string.h>#include "mikmod_internals.h"#ifdef SUNOSextern int fprintf(FILE *, const char *, ...);#endif/*========== Module structure */typedef struct XMHEADER {	CHAR  id[17];          /* ID text: 'Extended module: ' */	CHAR  songname[21];    /* Module name */	CHAR  trackername[20]; /* Tracker name */	UWORD version;         /* Version number */	ULONG headersize;      /* Header size */	UWORD songlength;      /* Song length (in patten order table) */	UWORD restart;         /* Restart position */	UWORD numchn;          /* Number of channels (2,4,6,8,10,...,32) */	UWORD numpat;          /* Number of patterns (max 256) */	UWORD numins;          /* Number of instruments (max 128) */	UWORD flags;       	UWORD tempo;           /* Default tempo */	UWORD bpm;             /* Default BPM */	UBYTE orders[256];     /* Pattern order table  */} XMHEADER;typedef struct XMINSTHEADER {	ULONG size;     /* Instrument size */	CHAR  name[22]; /* Instrument name */	UBYTE type;     /* Instrument type (always 0) */	UWORD numsmp;   /* Number of samples in instrument */	ULONG ssize;} XMINSTHEADER;#define XMENVCNT (12*2)#define XMNOTECNT (8*OCTAVE)typedef struct XMPATCHHEADER {	UBYTE what[XMNOTECNT];  /*  Sample number for all notes */	UWORD volenv[XMENVCNT]; /*  Points for volume envelope */	UWORD panenv[XMENVCNT]; /*  Points for panning envelope */	UBYTE volpts;      /*  Number of volume points */	UBYTE panpts;      /*  Number of panning points */	UBYTE volsus;      /*  Volume sustain point */	UBYTE volbeg;      /*  Volume loop start point */	UBYTE volend;      /*  Volume loop end point */	UBYTE pansus;      /*  Panning sustain point */	UBYTE panbeg;      /*  Panning loop start point */	UBYTE panend;      /*  Panning loop end point */	UBYTE volflg;      /*  Volume type: bit 0: On; 1: Sustain; 2: Loop */	UBYTE panflg;      /*  Panning type: bit 0: On; 1: Sustain; 2: Loop */	UBYTE vibflg;      /*  Vibrato type */	UBYTE vibsweep;    /*  Vibrato sweep */	UBYTE vibdepth;    /*  Vibrato depth */	UBYTE vibrate;     /*  Vibrato rate */	UWORD volfade;     /*  Volume fadeout */} XMPATCHHEADER;typedef struct XMWAVHEADER {	ULONG length;         /* Sample length */	ULONG loopstart;      /* Sample loop start */	ULONG looplength;     /* Sample loop length */	UBYTE volume;         /* Volume  */	SBYTE finetune;       /* Finetune (signed byte -128..+127) */	UBYTE type;           /* Loop type */	UBYTE panning;        /* Panning (0-255) */	SBYTE relnote;        /* Relative note number (signed byte) */	UBYTE reserved;	CHAR  samplename[22]; /* Sample name */	UBYTE vibtype;        /* Vibrato type */	UBYTE vibsweep;       /* Vibrato sweep */	UBYTE vibdepth;       /* Vibrato depth */	UBYTE vibrate;        /* Vibrato rate */} XMWAVHEADER;typedef struct XMPATHEADER {	ULONG size;     /* Pattern header length  */	UBYTE packing;  /* Packing type (always 0) */	UWORD numrows;  /* Number of rows in pattern (1..256) */	SWORD packsize; /* Packed patterndata size */} XMPATHEADER;typedef struct XMNOTE {	UBYTE note,ins,vol,eff,dat;} XMNOTE;/*========== Loader variables */static	XMNOTE *xmpat=NULL;static	XMHEADER *mh=NULL;/* increment unit for sample array reallocation */#define XM_SMPINCR 64static	ULONG *nextwav=NULL;static	XMWAVHEADER *wh=NULL,*s=NULL;/*========== Loader code */BOOL XM_Test(void){	UBYTE id[38];	if(!_mm_read_UBYTES(id,38,modreader)) return 0;	if(memcmp(id,"Extended Module: ",17)) return 0;	if(id[37]==0x1a) return 1;	return 0;}BOOL XM_Init(void){	if(!(mh=(XMHEADER *)_mm_malloc(sizeof(XMHEADER)))) return 0;	return 1;}void XM_Cleanup(void){	_mm_free(mh);}static int XM_ReadNote(XMNOTE* n){	UBYTE cmp,result=1;	memset(n,0,sizeof(XMNOTE));	cmp=_mm_read_UBYTE(modreader);	if(cmp&0x80) {		if(cmp&1)  { result++;n->note = _mm_read_UBYTE(modreader); }		if(cmp&2)  { result++;n->ins  = _mm_read_UBYTE(modreader); }		if(cmp&4)  { result++;n->vol  = _mm_read_UBYTE(modreader); }		if(cmp&8)  { result++;n->eff  = _mm_read_UBYTE(modreader); }		if(cmp&16) { result++;n->dat  = _mm_read_UBYTE(modreader); }	} else {		n->note = cmp;		n->ins  = _mm_read_UBYTE(modreader);		n->vol  = _mm_read_UBYTE(modreader);		n->eff  = _mm_read_UBYTE(modreader);		n->dat  = _mm_read_UBYTE(modreader);		result += 4;	}	return result;}static UBYTE* XM_Convert(XMNOTE* xmtrack,UWORD rows){	int t;	UBYTE note,ins,vol,eff,dat;	UniReset();	for(t=0;t<rows;t++) {		note = xmtrack->note;		ins  = xmtrack->ins;		vol  = xmtrack->vol;		eff  = xmtrack->eff;		dat  = xmtrack->dat;		if(note) {			if(note>XMNOTECNT)				UniEffect(UNI_KEYFADE,0);			else				UniNote(note-1);		}		if(ins) UniInstrument(ins-1);		switch(vol>>4) {			case 0x6: /* volslide down */				if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol&0xf);				break;			case 0x7: /* volslide up */				if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol<<4);				break;				/* volume-row fine volume slide is compatible with protracker				   EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as				   opposed to 'take the last sliding value'. */			case 0x8: /* finevol down */				UniPTEffect(0xe,0xb0|(vol&0xf));				break;			case 0x9: /* finevol up */				UniPTEffect(0xe,0xa0|(vol&0xf));				break;			case 0xa: /* set vibrato speed */				UniEffect(UNI_XMEFFECT4,vol<<4);				break;			case 0xb: /* vibrato */				UniEffect(UNI_XMEFFECT4,vol&0xf);				break;			case 0xc: /* set panning */				UniPTEffect(0x8,vol<<4);				break;			case 0xd: /* panning slide left (only slide when data not zero) */				if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol&0xf);				break;			case 0xe: /* panning slide right (only slide when data not zero) */				if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol<<4);				break;			case 0xf: /* tone porta */				UniPTEffect(0x3,vol<<4);				break;			default:				if((vol>=0x10)&&(vol<=0x50))					UniPTEffect(0xc,vol-0x10);		}		switch(eff) {			case 0x4:				UniEffect(UNI_XMEFFECT4,dat);				break;			case 0x6:				UniEffect(UNI_XMEFFECT6,dat);				break;			case 0xa:				UniEffect(UNI_XMEFFECTA,dat);				break;			case 0xe: /* Extended effects */				switch(dat>>4) {					case 0x1: /* XM fine porta up */						UniEffect(UNI_XMEFFECTE1,dat&0xf);						break;					case 0x2: /* XM fine porta down */						UniEffect(UNI_XMEFFECTE2,dat&0xf);						break;					case 0xa: /* XM fine volume up */						UniEffect(UNI_XMEFFECTEA,dat&0xf);						break;					case 0xb: /* XM fine volume down */						UniEffect(UNI_XMEFFECTEB,dat&0xf);						break;					default:						UniPTEffect(eff,dat);				}				break;			case 'G'-55: /* G - set global volume */				UniEffect(UNI_XMEFFECTG,dat>64?128:dat<<1);				break;			case 'H'-55: /* H - global volume slide */				UniEffect(UNI_XMEFFECTH,dat);				break;			case 'K'-55: /* K - keyOff and KeyFade */				UniEffect(UNI_KEYFADE,dat);				break;			case 'L'-55: /* L - set envelope position */				UniEffect(UNI_XMEFFECTL,dat);				break;			case 'P'-55: /* P - panning slide */				UniEffect(UNI_XMEFFECTP,dat);				break;			case 'R'-55: /* R - multi retrig note */				UniEffect(UNI_S3MEFFECTQ,dat);				break;			case 'T'-55: /* T - Tremor */				UniEffect(UNI_S3MEFFECTI,dat);				break;			case 'X'-55:				switch(dat>>4) {					case 1: /* X1 - Extra Fine Porta up */						UniEffect(UNI_XMEFFECTX1,dat&0xf);						break;					case 2: /* X2 - Extra Fine Porta down */						UniEffect(UNI_XMEFFECTX2,dat&0xf);						break;				}				break;			default:				if(eff<=0xf) {					/* the pattern jump destination is written in decimal,					   but it seems some poor tracker software writes them					   in hexadecimal... (sigh) */					if (eff==0xd)						/* don't change anything if we're sure it's in hexa */						if ((((dat&0xf0)>>4)<=9)&&((dat&0xf)<=9))							/* otherwise, convert from dec to hex */							dat=(((dat&0xf0)>>4)*10)+(dat&0xf);					UniPTEffect(eff,dat);				}				break;		}		UniNewline();		xmtrack++;	}	return UniDup();}static BOOL LoadPatterns(BOOL dummypat){	int t,u,v,numtrk;	if(!AllocTracks()) return 0;	if(!AllocPatterns()) return 0;	numtrk=0;	for(t=0;t<mh->numpat;t++) {		XMPATHEADER ph;		ph.size     =_mm_read_I_ULONG(modreader);		if (ph.size<(mh->version==0x0102?8:9)) {			_mm_errno=MMERR_LOADING_PATTERN;			return 0;		}		ph.packing  =_mm_read_UBYTE(modreader);		if(ph.packing) {			_mm_errno=MMERR_LOADING_PATTERN;			return 0;		}		if(mh->version==0x0102)			ph.numrows  =_mm_read_UBYTE(modreader)+1;		else			ph.numrows  =_mm_read_I_UWORD(modreader);		ph.packsize =_mm_read_I_UWORD(modreader);		ph.size-=(mh->version==0x0102?8:9);		if(ph.size)			_mm_fseek(modreader,ph.size,SEEK_CUR);		of.pattrows[t]=ph.numrows;		if(ph.numrows) {			if(!(xmpat=(XMNOTE*)_mm_calloc(ph.numrows*of.numchn,sizeof(XMNOTE))))				return 0;			/* when packsize is 0, don't try to load a pattern.. it's empty. */			if(ph.packsize) 				for(u=0;u<ph.numrows;u++) 					for(v=0;v<of.numchn;v++) {						if(!ph.packsize) break;						ph.packsize-=XM_ReadNote(&xmpat[(v*ph.numrows)+u]);						if(ph.packsize<0) {							free(xmpat);xmpat=NULL;							_mm_errno=MMERR_LOADING_PATTERN;							return 0;						}					}			if(ph.packsize) {				_mm_fseek(modreader,ph.packsize,SEEK_CUR);			}			if(_mm_eof(modreader)) {				free(xmpat);xmpat=NULL;				_mm_errno=MMERR_LOADING_PATTERN;				return 0;			}			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 void FixEnvelope(ENVPT *cur, int pts){		int u, old, tmp;

⌨️ 快捷键说明

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