📄 load_uni.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_uni.c,v 1.2 2004/02/06 19:29:03 raph Exp $ UNIMOD (libmikmod's and APlayer's internal module format) 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 UNIHEADER { CHAR id[4]; UBYTE numchn; UWORD numpos; UWORD reppos; UWORD numpat; UWORD numtrk; UWORD numins; UWORD numsmp; UBYTE initspeed; UBYTE inittempo; UBYTE initvolume; UWORD flags; UBYTE numvoices; UWORD bpmlimit; UBYTE positions[256]; UBYTE panning[32];} UNIHEADER;typedef struct UNISMP05 { UWORD c2spd; UWORD transpose; UBYTE volume; UBYTE panning; ULONG length; ULONG loopstart; ULONG loopend; UWORD flags; CHAR* samplename; UBYTE vibtype; UBYTE vibsweep; UBYTE vibdepth; UBYTE vibrate;} UNISMP05;/*========== Loader variables */static UWORD universion;static UNIHEADER mh;#define UNI_SMPINCR 64static UNISMP05 *wh=NULL,*s=NULL;/*========== Loader code */static char* readstring(void){ char *s=NULL; UWORD len; len=_mm_read_I_UWORD(modreader); if(len) { s=_mm_malloc(len+1); _mm_read_UBYTES(s,len,modreader); s[len]=0; } return s;}BOOL UNI_Test(void){ char id[6]; if(!_mm_read_UBYTES(id,6,modreader)) return 0; /* UNIMod created by MikCvt */ if(!(memcmp(id,"UN0",3))) { if((id[3]>='4')&&(id[3]<='6')) return 1; } /* UNIMod created by APlayer */ if(!(memcmp(id,"APUN\01",5))) { if((id[5]>=1)&&(id[5]<=6)) return 1; } return 0;}BOOL UNI_Init(void){ return 1;}void UNI_Cleanup(void){ _mm_free(wh); s=NULL;}static UBYTE* readtrack(void){ UBYTE *t; UWORD len; int cur=0,chunk; if(universion>=6) len=_mm_read_M_UWORD(modreader); else len=_mm_read_I_UWORD(modreader); if(!len) return NULL; if(!(t=_mm_malloc(len))) return NULL; _mm_read_UBYTES(t,len,modreader); /* Check if the track is correct */ while(1) { chunk=t[cur++]; if(!chunk) break; chunk=(chunk&0x1f)-1; while(chunk>0) { int opcode,oplen; if(cur>=len) { free(t); return NULL; } opcode=t[cur]; /* Remap opcodes */ if (universion <= 5) { if (opcode > 29) { free(t); return NULL; } switch (opcode) { /* UNI_NOTE .. UNI_S3MEFFECTQ are the same */ case 25: opcode = UNI_S3MEFFECTT; break; case 26: opcode = UNI_XMEFFECTA; break; case 27: opcode = UNI_XMEFFECTG; break; case 28: opcode = UNI_XMEFFECTH; break; case 29: opcode = UNI_XMEFFECTP; break; } } else { /* APlayer < 1.05 does not have XMEFFECT6 */ if (opcode >= UNI_XMEFFECT6 && universion < 0x105) opcode++; /* APlayer < 1.03 does not have ITEFFECTT */ if (opcode >= UNI_ITEFFECTT && universion < 0x103) opcode++; /* APlayer < 1.02 does not have ITEFFECTZ */ if (opcode >= UNI_ITEFFECTZ && universion < 0x102) opcode++; } if((!opcode)||(opcode>=UNI_LAST)) { free(t); return NULL; } t[cur]=opcode; oplen=unioperands[opcode]+1; cur+=oplen; chunk-=oplen; } if((chunk<0)||(cur>=len)) { free(t); return NULL; } } return t;}static BOOL loadsmp6(void){ int t; SAMPLE *s; s=of.samples; for(t=0;t<of.numsmp;t++,s++) { int flags; flags = _mm_read_M_UWORD(modreader); s->flags=0; if(flags&0x0004) s->flags|=SF_STEREO; if(flags&0x0002) s->flags|=SF_SIGNED; if(flags&0x0001) s->flags|=SF_16BITS; /* convert flags */ if(universion>=0x104) { if(flags&0x2000) s->flags|=SF_UST_LOOP; if(flags&0x1000) s->flags|=SF_OWNPAN; if(flags&0x0800) s->flags|=SF_SUSTAIN; if(flags&0x0400) s->flags|=SF_REVERSE; if(flags&0x0200) s->flags|=SF_BIDI; if(flags&0x0100) s->flags|=SF_LOOP; if(flags&0x0020) s->flags|=SF_ITPACKED; if(flags&0x0010) s->flags|=SF_DELTA; if(flags&0x0008) s->flags|=SF_BIG_ENDIAN; } else if(universion>=0x102) { if(flags&0x0800) s->flags|=SF_UST_LOOP; if(flags&0x0400) s->flags|=SF_OWNPAN; if(flags&0x0200) s->flags|=SF_SUSTAIN; if(flags&0x0100) s->flags|=SF_REVERSE; if(flags&0x0080) s->flags|=SF_BIDI; if(flags&0x0040) s->flags|=SF_LOOP; if(flags&0x0020) s->flags|=SF_ITPACKED; if(flags&0x0010) s->flags|=SF_DELTA; if(flags&0x0008) s->flags|=SF_BIG_ENDIAN; } else { if(flags&0x400) s->flags|=SF_UST_LOOP; if(flags&0x200) s->flags|=SF_OWNPAN; if(flags&0x100) s->flags|=SF_REVERSE; if(flags&0x080) s->flags|=SF_SUSTAIN; if(flags&0x040) s->flags|=SF_BIDI; if(flags&0x020) s->flags|=SF_LOOP; if(flags&0x010) s->flags|=SF_BIG_ENDIAN; if(flags&0x008) s->flags|=SF_DELTA; } s->speed = _mm_read_M_ULONG(modreader); s->volume = _mm_read_UBYTE(modreader); s->panning = _mm_read_M_UWORD(modreader); s->length = _mm_read_M_ULONG(modreader); s->loopstart = _mm_read_M_ULONG(modreader); s->loopend = _mm_read_M_ULONG(modreader); s->susbegin = _mm_read_M_ULONG(modreader); s->susend = _mm_read_M_ULONG(modreader); s->globvol = _mm_read_UBYTE(modreader); s->vibflags = _mm_read_UBYTE(modreader); s->vibtype = _mm_read_UBYTE(modreader); s->vibsweep = _mm_read_UBYTE(modreader); s->vibdepth = _mm_read_UBYTE(modreader); s->vibrate = _mm_read_UBYTE(modreader); s->samplename=readstring(); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } } return 1;}static BOOL loadinstr6(void){ int t,w; INSTRUMENT *i; i=of.instruments; for(t=0;t<of.numins;t++,i++) { i->flags = _mm_read_UBYTE(modreader); i->nnatype = _mm_read_UBYTE(modreader); i->dca = _mm_read_UBYTE(modreader); i->dct = _mm_read_UBYTE(modreader); i->globvol = _mm_read_UBYTE(modreader); i->panning = _mm_read_M_UWORD(modreader); i->pitpansep = _mm_read_UBYTE(modreader); i->pitpancenter = _mm_read_UBYTE(modreader); i->rvolvar = _mm_read_UBYTE(modreader); i->rpanvar = _mm_read_UBYTE(modreader); i->volfade = _mm_read_M_UWORD(modreader);#if defined __STDC__ || defined _MSC_VER || defined MPW_C#define UNI_LoadEnvelope6(name) \ i-> name##flg=_mm_read_UBYTE(modreader); \ i-> name##pts=_mm_read_UBYTE(modreader); \ i-> name##susbeg=_mm_read_UBYTE(modreader); \ i-> name##susend=_mm_read_UBYTE(modreader); \ i-> name##beg=_mm_read_UBYTE(modreader); \ i-> name##end=_mm_read_UBYTE(modreader); \ for(w=0;w<(universion>=0x100?32:i-> name##pts);w++) { \ i-> name##env[w].pos=_mm_read_M_SWORD(modreader); \ i-> name##env[w].val=_mm_read_M_SWORD(modreader); \ }#else#define UNI_LoadEnvelope6(name) \ i-> name/**/flg=_mm_read_UBYTE(modreader); \ i-> name/**/pts=_mm_read_UBYTE(modreader); \ i-> name/**/susbeg=_mm_read_UBYTE(modreader); \ i-> name/**/susend=_mm_read_UBYTE(modreader); \ i-> name/**/beg=_mm_read_UBYTE(modreader); \ i-> name/**/end=_mm_read_UBYTE(modreader); \ for (w=0;w<(universion>=0x100?32:i-> name/**/pts);w++) { \ i-> name/**/env[w].pos=_mm_read_M_SWORD(modreader); \ i-> name/**/env[w].val=_mm_read_M_SWORD(modreader); \ }#endif UNI_LoadEnvelope6(vol); UNI_LoadEnvelope6(pan); UNI_LoadEnvelope6(pit);#undef UNI_LoadEnvelope6 if(universion>=0x103) _mm_read_M_UWORDS(i->samplenumber,120,modreader); else for(w=0;w<120;w++) i->samplenumber[w]=_mm_read_UBYTE(modreader); _mm_read_UBYTES(i->samplenote,120,modreader); i->insname=readstring(); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } } return 1;}static BOOL loadinstr5(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -