📄 load_uni.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_uni.c,v 1.13 1999/10/25 16:31:41 miod Exp $ UNIMOD (libmikmod's and APlayer's internal module format) loader==============================================================================*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "unimod_priv.h"/*========== 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; UBYTE flags; UBYTE numvoices; 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] <= 4)) 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 { if (opcode > UNI_ITEFFECTP) { /* APlayer < 1.03 does not have ITEFFECTT */ if (universion < 0x103) opcode++; /* APlayer < 1.02 does not have ITEFFECTZ */ if ((opcode > UNI_ITEFFECTY) && (universion < 0x102)) opcode++; } } if ((!opcode) || (opcode >= UNI_LAST)) { free (t); return NULL; } 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 & 0x0100) s->flags |= SF_REVERSE; 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 >= 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 & 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 & 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);#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); \ } 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){ INSTRUMENT *i; int t; UWORD wavcnt = 0; UBYTE vibtype, vibsweep, vibdepth, vibrate; i = of.instruments; for (of.numsmp = t = 0; t < of.numins; t++, i++) { int u, numsmp; numsmp = _mm_read_UBYTE (modreader); memset (i->samplenumber, 0xff, INSTNOTES * sizeof (UWORD)); for (u = 0; u < 96; u++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -