📄 load_med.c
字号:
numtracks = _mm_read_UBYTE (modreader); numlines = _mm_read_UBYTE (modreader); of.pattrows[t] = ++numlines; memset (mmdp = mmd0pat, 0, of.numchn * maxlines * sizeof (MMD0NOTE)); for (row = numlines; row; row--) { for (col = numtracks; col; col--, mmdp++) { mmdp->a = _mm_read_UBYTE (modreader); mmdp->b = _mm_read_UBYTE (modreader); mmdp->c = _mm_read_UBYTE (modreader); } } for (col = 0; col < of.numchn; col++) of.tracks[track++] = MED_Convert0 (numlines, col); } return 1;}static BOOL LoadMMD1Patterns (void){ int t, row, col; UWORD numtracks, numlines, maxlines = 0, track = 0; MMD1NOTE *mmdp; /* first, scan patterns to see how many channels are used */ for (t = 0; t < of.numpat; t++) { _mm_fseek (modreader, ba[t], SEEK_SET); numtracks = _mm_read_M_UWORD (modreader); numlines = _mm_read_M_UWORD (modreader); if (numtracks > of.numchn) of.numchn = numtracks; if (numlines > maxlines) maxlines = numlines; } of.numtrk = of.numpat * of.numchn; if (!AllocTracks ()) return 0; if (!AllocPatterns ()) return 0; if (!(mmd1pat = (MMD1NOTE *) _mm_calloc (of.numchn * (maxlines + 1), sizeof (MMD1NOTE)))) return 0; /* second read: really read and convert patterns */ for (t = 0; t < of.numpat; t++) { _mm_fseek (modreader, ba[t], SEEK_SET); numtracks = _mm_read_M_UWORD (modreader); numlines = _mm_read_M_UWORD (modreader); _mm_fseek (modreader, sizeof (ULONG), SEEK_CUR); of.pattrows[t] = ++numlines; memset (mmdp = mmd1pat, 0, of.numchn * maxlines * sizeof (MMD1NOTE)); for (row = numlines; row; row--) { for (col = numtracks; col; col--, mmdp++) { mmdp->a = _mm_read_UBYTE (modreader); mmdp->b = _mm_read_UBYTE (modreader); mmdp->c = _mm_read_UBYTE (modreader); mmdp->d = _mm_read_UBYTE (modreader); } } for (col = 0; col < of.numchn; col++) of.tracks[track++] = MED_Convert1 (numlines, col); } return 1;}BOOL MED_Load (BOOL curious){ int t; ULONG sa[64]; MEDINSTHEADER s; SAMPLE *q; MEDSAMPLE *mss; /* try to read module header */ mh->id = _mm_read_M_ULONG (modreader); mh->modlen = _mm_read_M_ULONG (modreader); mh->pMEDSONG = _mm_read_M_ULONG (modreader); mh->psecnum = _mm_read_M_UWORD (modreader); mh->pseq = _mm_read_M_UWORD (modreader); mh->pMEDBLOCKP = _mm_read_M_ULONG (modreader); mh->reserved1 = _mm_read_M_ULONG (modreader); mh->ppMedInstrHdr = _mm_read_M_ULONG (modreader); mh->reserved2 = _mm_read_M_ULONG (modreader); mh->pMEDEXP = _mm_read_M_ULONG (modreader); mh->reserved3 = _mm_read_M_ULONG (modreader); mh->pstate = _mm_read_M_UWORD (modreader); mh->pblock = _mm_read_M_UWORD (modreader); mh->pline = _mm_read_M_UWORD (modreader); mh->pseqnum = _mm_read_M_UWORD (modreader); mh->actplayline = _mm_read_M_SWORD (modreader); mh->counter = _mm_read_UBYTE (modreader); mh->extra_songs = _mm_read_UBYTE (modreader); /* Seek to MEDSONG struct */ _mm_fseek (modreader, mh->pMEDSONG, SEEK_SET); /* Load the MMD0 Song Header */ mss = ms->sample; /* load the sample data first */ for (t = 63; t; t--, mss++) { mss->rep = _mm_read_M_UWORD (modreader); mss->replen = _mm_read_M_UWORD (modreader); mss->midich = _mm_read_UBYTE (modreader); mss->midipreset = _mm_read_UBYTE (modreader); mss->svol = _mm_read_UBYTE (modreader); mss->strans = _mm_read_SBYTE (modreader); } ms->numblocks = _mm_read_M_UWORD (modreader); ms->songlen = _mm_read_M_UWORD (modreader); _mm_read_UBYTES (ms->playseq, 256, modreader); ms->deftempo = _mm_read_M_UWORD (modreader); ms->playtransp = _mm_read_SBYTE (modreader); ms->flags = _mm_read_UBYTE (modreader); ms->flags2 = _mm_read_UBYTE (modreader); ms->tempo2 = _mm_read_UBYTE (modreader); _mm_read_UBYTES (ms->trkvol, 16, modreader); ms->mastervol = _mm_read_UBYTE (modreader); ms->numsamples = _mm_read_UBYTE (modreader); /* check for a bad header */ if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* load extension structure */ if (mh->pMEDEXP) { _mm_fseek (modreader, mh->pMEDEXP, SEEK_SET); me->nextmod = _mm_read_M_ULONG (modreader); me->exp_smp = _mm_read_M_ULONG (modreader); me->s_ext_entries = _mm_read_M_UWORD (modreader); me->s_ext_entrsz = _mm_read_M_UWORD (modreader); me->annotxt = _mm_read_M_ULONG (modreader); me->annolen = _mm_read_M_ULONG (modreader); me->iinfo = _mm_read_M_ULONG (modreader); me->i_ext_entries = _mm_read_M_UWORD (modreader); me->i_ext_entrsz = _mm_read_M_UWORD (modreader); me->jumpmask = _mm_read_M_ULONG (modreader); me->rgbtable = _mm_read_M_ULONG (modreader); me->channelsplit = _mm_read_M_ULONG (modreader); me->n_info = _mm_read_M_ULONG (modreader); me->songname = _mm_read_M_ULONG (modreader); me->songnamelen = _mm_read_M_ULONG (modreader); me->dumps = _mm_read_M_ULONG (modreader); } /* seek to and read the samplepointer array */ _mm_fseek (modreader, mh->ppMedInstrHdr, SEEK_SET); if (!_mm_read_M_ULONGS (sa, ms->numsamples, modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* alloc and read the blockpointer array */ if (!(ba = (ULONG *) _mm_calloc (ms->numblocks, sizeof (ULONG)))) return 0; _mm_fseek (modreader, mh->pMEDBLOCKP, SEEK_SET); if (!_mm_read_M_ULONGS (ba, ms->numblocks, modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* copy song positions */ if (!AllocPositions (ms->songlen)) return 0; for (t = 0; t < ms->songlen; t++) of.positions[t] = ms->playseq[t]; decimalvolumes = (ms->flags & 0x10) ? 0 : 1; bpmtempos = (ms->flags2 & 0x20) ? 1 : 0; if (bpmtempos) { int bpmlen = (ms->flags2 & 0x1f) + 1; of.initspeed = ms->tempo2; of.inittempo = ms->deftempo * bpmlen / 4; if (bpmlen != 4) { /* Let's do some math : compute GCD of BPM beat length and speed */ int a, b; a = bpmlen; b = ms->tempo2; if (a > b) { t = b; b = a; a = t; } while ((a != b) && (a)) { t = a; a = b - a; b = t; if (a > b) { t = b; b = a; a = t; } } of.initspeed /= b; of.inittempo = ms->deftempo * bpmlen / (4 * b); } } else { of.initspeed = ms->tempo2; of.inittempo = ms->deftempo ? ((UWORD) ms->deftempo * 125) / 33 : 128; if ((ms->deftempo <= 10) && (ms->deftempo)) of.inittempo = (of.inittempo * 33) / 6; of.flags |= UF_HIGHBPM; } MED_Version[12] = mh->id; of.modtype = strdup (MED_Version); of.numchn = 0; /* will be counted later */ of.numpat = ms->numblocks; of.numpos = ms->songlen; of.numins = ms->numsamples; of.numsmp = of.numins; of.reppos = 0; if ((mh->pMEDEXP) && (me->songname) && (me->songnamelen)) { char *name; _mm_fseek (modreader, me->songname, SEEK_SET); name = _mm_malloc (me->songnamelen); _mm_read_UBYTES (name, me->songnamelen, modreader); of.songname = DupStr (name, me->songnamelen, 1); free (name); } else of.songname = DupStr (NULL, 0, 0); if ((mh->pMEDEXP) && (me->annotxt) && (me->annolen)) { _mm_fseek (modreader, me->annotxt, SEEK_SET); ReadComment (me->annolen); } if (!AllocSamples ()) return 0; q = of.samples; for (t = 0; t < of.numins; t++) { q->flags = SF_SIGNED; q->volume = 64; if (sa[t]) { _mm_fseek (modreader, sa[t], SEEK_SET); s.length = _mm_read_M_ULONG (modreader); s.type = _mm_read_M_SWORD (modreader); if (s.type) {#ifdef MIKMOD_DEBUG fputs ("\rNon-sample instruments not supported in MED loader yet\n", stderr);#endif if (!curious) { _mm_errno = MMERR_MED_SYNTHSAMPLES; return 0; } s.length = 0; } if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } q->length = s.length; q->seekpos = _mm_ftell (modreader); q->loopstart = ms->sample[t].rep << 1; q->loopend = q->loopstart + (ms->sample[t].replen << 1); if (ms->sample[t].replen > 1) q->flags |= SF_LOOP; /* don't load sample if length>='MMD0'... such kluges make libmikmod's code unique !!! */ if (q->length >= MMD0_string) q->length = 0; } else q->length = 0; if ((mh->pMEDEXP) && (me->exp_smp) && (t < me->s_ext_entries) && (me->s_ext_entrsz >= 4)) { MEDINSTEXT ie; _mm_fseek (modreader, me->exp_smp + t * me->s_ext_entrsz, SEEK_SET); ie.hold = _mm_read_UBYTE (modreader); ie.decay = _mm_read_UBYTE (modreader); ie.suppress_midi_off = _mm_read_UBYTE (modreader); ie.finetune = _mm_read_SBYTE (modreader); q->speed = finetune[ie.finetune & 0xf]; } else q->speed = 8363; if ((mh->pMEDEXP) && (me->iinfo) && (t < me->i_ext_entries) && (me->i_ext_entrsz >= 40)) { MEDINSTINFO ii; _mm_fseek (modreader, me->iinfo + t * me->i_ext_entrsz, SEEK_SET); _mm_read_UBYTES (ii.name, 40, modreader); q->samplename = DupStr ((CHAR *) ii.name, 40, 1); } else q->samplename = NULL; q++; } if (mh->id == MMD0_string) { if (!LoadMMD0Patterns ()) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } } else if (mh->id == MMD1_string) { if (!LoadMMD1Patterns ()) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } } else { _mm_errno = MMERR_NOT_A_MODULE; return 0; } return 1;}/*========== Loader information */MLOADER load_med ={ NULL, "MED", "MED (OctaMED)", MED_Init, MED_Test, MED_Load, MED_Cleanup, NULL};/* ex:set ts=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -