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

📄 load_stm.c

📁 wince下著名的视频播放器源码
💻 C
字号:
/*	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_stm.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $  Screamtracker 2 (STM) 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 *//* sample information */typedef struct STMSAMPLE {	CHAR  filename[12];	UBYTE unused;       /* 0x00 */	UBYTE instdisk;     /* Instrument disk */	UWORD reserved;	UWORD length;       /* Sample length */	UWORD loopbeg;      /* Loop start point */	UWORD loopend;      /* Loop end point */	UBYTE volume;       /* Volume */	UBYTE reserved2;	UWORD c2spd;        /* Good old c2spd */	ULONG reserved3;	UWORD isa;} STMSAMPLE;/* header */typedef struct STMHEADER {	CHAR  songname[20];	CHAR  trackername[8]; /* !Scream! for ST 2.xx  */	UBYTE unused;         /* 0x1A  */	UBYTE filetype;       /* 1=song, 2=module */	UBYTE ver_major;	UBYTE ver_minor;	UBYTE inittempo;      /* initspeed= stm inittempo>>4  */	UBYTE numpat;         /* number of patterns  */	UBYTE globalvol;     	UBYTE reserved[13];	STMSAMPLE sample[31]; /* STM sample data */	UBYTE patorder[128];  /* Docs say 64 - actually 128 */} STMHEADER;typedef struct STMNOTE {	UBYTE note,insvol,volcmd,cmdinf;} STMNOTE;/*========== Loader variables */static STMNOTE *stmbuf = NULL;static STMHEADER *mh = NULL;/* tracker identifiers */static CHAR* STM_Version[STM_NTRACKERS] = {	"Screamtracker 2",	"Converted by MOD2STM (STM format)",	"Wuzamod (STM format)"};/*========== Loader code */BOOL STM_Test(void){	UBYTE str[44];	int t;	_mm_fseek(modreader,20,SEEK_SET);	_mm_read_UBYTES(str,44,modreader);	if(str[9]!=2) return 0;	/* STM Module = filetype 2 */	/* Prevent false positives for S3M files */	if(!memcmp(str+40,"SCRM",4))		return 0;		for (t=0;t<STM_NTRACKERS;t++)		if(!memcmp(str,STM_Signatures[t],8))			return 1;	return 0;}BOOL STM_Init(void){	if(!(mh=(STMHEADER*)_mm_malloc(sizeof(STMHEADER)))) return 0;	if(!(stmbuf=(STMNOTE*)_mm_calloc(64U*4,sizeof(STMNOTE)))) return 0;	return 1;}static void STM_Cleanup(void){	_mm_free(mh);	_mm_free(stmbuf);}static void STM_ConvertNote(STMNOTE *n){	UBYTE note,ins,vol,cmd,inf;	/* extract the various information from the 4 bytes that make up a note */	note = n->note;	ins  = n->insvol>>3;	vol  = (n->insvol&7)+((n->volcmd&0x70)>>1);	cmd  = n->volcmd&15;	inf  = n->cmdinf;	if((ins)&&(ins<32)) UniInstrument(ins-1);	/* special values of [SBYTE0] are handled here 	   we have no idea if these strange values will ever be encountered.	   but it appears as those stms sound correct. */	if((note==254)||(note==252)) {		UniPTEffect(0xc,0); /* note cut */		n->volcmd|=0x80;	} else		/* if note < 251, then all three bytes are stored in the file */	  if(note<251) UniNote((((note>>4)+2)*OCTAVE)+(note&0xf));	if((!(n->volcmd&0x80))&&(vol<65)) UniPTEffect(0xc,vol);	if(cmd!=255)		switch(cmd) {			case 1:	/* Axx set speed to xx */				UniPTEffect(0xf,inf>>4);				break;			case 2:	/* Bxx position jump */				UniPTEffect(0xb,inf);				break;			case 3:	/* Cxx patternbreak to row xx */				UniPTEffect(0xd,(((inf&0xf0)>>4)*10)+(inf&0xf));				break;			case 4:	/* Dxy volumeslide */				UniEffect(UNI_S3MEFFECTD,inf);				break;			case 5:	/* Exy toneslide down */				UniEffect(UNI_S3MEFFECTE,inf);				break;			case 6:	/* Fxy toneslide up */				UniEffect(UNI_S3MEFFECTF,inf);				break;			case 7:	/* Gxx Tone portamento,speed xx */				UniPTEffect(0x3,inf);				break;			case 8:	/* Hxy vibrato */				UniPTEffect(0x4,inf);				break;			case 9:	/* Ixy tremor, ontime x, offtime y */				UniEffect(UNI_S3MEFFECTI,inf);			break;			case 0:		/* protracker arpeggio */				if(!inf) break;				/* fall through */			case 0xa:	/* Jxy arpeggio */				UniPTEffect(0x0,inf);				break;			case 0xb:	/* Kxy Dual command H00 & Dxy */				UniPTEffect(0x4,0);				UniEffect(UNI_S3MEFFECTD,inf);				break;			case 0xc:	/* Lxy Dual command G00 & Dxy */				UniPTEffect(0x3,0);				UniEffect(UNI_S3MEFFECTD,inf);				break;			/* Support all these above, since ST2 can LOAD these values but can			   actually only play up to J - and J is only half-way implemented			   in ST2 */			case 0x18:	/* Xxx amiga panning command 8xx */				UniPTEffect(0x8,inf);				of.flags |= UF_PANNING;				break;		}}static UBYTE *STM_ConvertTrack(STMNOTE *n){	int t;	UniReset();	for(t=0;t<64;t++) {		STM_ConvertNote(n);		UniNewline();		n+=of.numchn;	}	return UniDup();}static BOOL STM_LoadPatterns(void){	int t,s,tracks=0;	if(!AllocPatterns()) return 0;	if(!AllocTracks()) return 0;	/* Allocate temporary buffer for loading and converting the patterns */	for(t=0;t<of.numpat;t++) {		for(s=0;s<(64U*of.numchn);s++) {			stmbuf[s].note   = _mm_read_UBYTE(modreader);			stmbuf[s].insvol = _mm_read_UBYTE(modreader);			stmbuf[s].volcmd = _mm_read_UBYTE(modreader);			stmbuf[s].cmdinf = _mm_read_UBYTE(modreader);		}		if(_mm_eof(modreader)) {			_mm_errno = MMERR_LOADING_PATTERN;			return 0;		}		for(s=0;s<of.numchn;s++)			if(!(of.tracks[tracks++]=STM_ConvertTrack(stmbuf+s))) return 0;	}	return 1;}BOOL STM_Load(BOOL curious){	int t; 	ULONG MikMod_ISA; /* We must generate our own ISA, it's not stored in stm */	SAMPLE *q;	/* try to read stm header */	_mm_read_string(mh->songname,20,modreader);	_mm_read_string(mh->trackername,8,modreader);	mh->unused      =_mm_read_UBYTE(modreader);	mh->filetype    =_mm_read_UBYTE(modreader);	mh->ver_major   =_mm_read_UBYTE(modreader);	mh->ver_minor   =_mm_read_UBYTE(modreader);	mh->inittempo   =_mm_read_UBYTE(modreader);	if(!mh->inittempo) {		_mm_errno=MMERR_NOT_A_MODULE;		return 0;	}	mh->numpat      =_mm_read_UBYTE(modreader);	mh->globalvol   =_mm_read_UBYTE(modreader);	_mm_read_UBYTES(mh->reserved,13,modreader);	for(t=0;t<31;t++) {		STMSAMPLE *s=&mh->sample[t];	/* STM sample data */		_mm_read_string(s->filename,12,modreader);		s->unused   =_mm_read_UBYTE(modreader);		s->instdisk =_mm_read_UBYTE(modreader);		s->reserved =_mm_read_I_UWORD(modreader);		s->length   =_mm_read_I_UWORD(modreader);		s->loopbeg  =_mm_read_I_UWORD(modreader);		s->loopend  =_mm_read_I_UWORD(modreader);		s->volume   =_mm_read_UBYTE(modreader);		s->reserved2=_mm_read_UBYTE(modreader);		s->c2spd    =_mm_read_I_UWORD(modreader);		s->reserved3=_mm_read_I_ULONG(modreader);		s->isa      =_mm_read_I_UWORD(modreader);	}	_mm_read_UBYTES(mh->patorder,128,modreader);	if(_mm_eof(modreader)) {		_mm_errno = MMERR_LOADING_HEADER;		return 0;	}	/* set module variables */	for(t=0;t<STM_NTRACKERS;t++)		if(!memcmp(mh->trackername,STM_Signatures[t],8)) break;	of.modtype   = strdup(STM_Version[t]);	of.songname  = DupStr(mh->songname,20,1); /* make a cstr of songname */	of.numpat    = mh->numpat;	of.inittempo = 125;                     /* mh->inittempo+0x1c; */	of.initspeed = mh->inittempo>>4;	of.numchn    = 4;                       /* get number of channels */	of.reppos    = 0;	of.flags    |= UF_S3MSLIDES;	of.bpmlimit  = 32;	t=0;	if(!AllocPositions(0x80)) return 0;	/* 99 terminates the patorder list */	while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) {		of.positions[t]=mh->patorder[t];		t++;	}	if(mh->patorder[t]<=99) t++;	of.numpos=t;	of.numtrk=of.numpat*of.numchn;	of.numins=of.numsmp=31;	if(!AllocSamples()) return 0;	if(!STM_LoadPatterns()) return 0;	MikMod_ISA=_mm_ftell(modreader);	MikMod_ISA=(MikMod_ISA+15)&0xfffffff0;	/* normalize */	for(q=of.samples,t=0;t<of.numsmp;t++,q++) {		/* load sample info */		q->samplename = DupStr(mh->sample[t].filename,12,1);		q->speed      = (mh->sample[t].c2spd * 8363) / 8448;		q->volume     = mh->sample[t].volume;		q->length     = mh->sample[t].length;		if (/*(!mh->sample[t].volume)||*/(q->length==1)) q->length=0;		q->loopstart  = mh->sample[t].loopbeg;		q->loopend    = mh->sample[t].loopend;		q->seekpos    = MikMod_ISA;		MikMod_ISA+=q->length;		MikMod_ISA=(MikMod_ISA+15)&0xfffffff0;	/* normalize */		/* contrary to the STM specs, sample data is signed */		q->flags = SF_SIGNED;		if(q->loopend && q->loopend != 0xffff)				q->flags|=SF_LOOP;	}	return 1;}CHAR *STM_LoadTitle(void){	CHAR s[20];	_mm_fseek(modreader,0,SEEK_SET);	if(!_mm_read_UBYTES(s,20,modreader)) return NULL;	return(DupStr(s,20,1));}/*========== Loader information */MIKMODAPI MLOADER load_stm={	NULL,	"STM",	"STM (Scream Tracker)",	STM_Init,	STM_Test,	STM_Load,	STM_Cleanup,	STM_LoadTitle};/* ex:set ts=4: */

⌨️ 快捷键说明

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