📄 load_imf.c
字号:
UniPTEffect (0xc, 0); /* Note cut */ if (tr[t].eff1 == 0x0c) tr[t].eff1 = 0; if (tr[t].eff2 == 0x0c) tr[t].eff2 = 0; } else UniNote (((note >> 4) * OCTAVE) + (note & 0xf)); } IMF_ProcessCmd (tr[t].eff1, tr[t].dat1); IMF_ProcessCmd (tr[t].eff2, tr[t].dat2); UniNewline (); } return UniDup ();}BOOL IMF_Load (BOOL curious){#define IMF_SMPINCR 64 int t, u, track = 0; IMFCHANNEL channels[32]; INSTRUMENT *d; SAMPLE *q; IMFWAVHEADER *wh = NULL, *s = NULL; ULONG *nextwav = NULL; UWORD wavcnt = 0; UBYTE id[4]; /* try to read the module header */ _mm_read_string (mh->songname, 32, modreader); mh->ordnum = _mm_read_I_UWORD (modreader); mh->patnum = _mm_read_I_UWORD (modreader); mh->insnum = _mm_read_I_UWORD (modreader); mh->flags = _mm_read_I_UWORD (modreader); _mm_fseek (modreader, 8, SEEK_CUR); mh->initspeed = _mm_read_UBYTE (modreader); mh->inittempo = _mm_read_UBYTE (modreader); mh->mastervol = _mm_read_UBYTE (modreader); mh->mastermult = _mm_read_UBYTE (modreader); _mm_fseek (modreader, 64, SEEK_SET); if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* set module variables */ of.songname = DupStr (mh->songname, 31, 1); of.modtype = strdup (IMF_Version); of.numpat = mh->patnum; of.numins = mh->insnum; of.reppos = 0; of.initspeed = mh->initspeed; of.inittempo = mh->inittempo; of.initvolume = mh->mastervol << 1; of.flags |= UF_INST; if (mh->flags & 1) of.flags |= UF_LINEAR; /* read channel information */ of.numchn = 0; memset (remap, -1, 32 * sizeof (UBYTE)); for (t = 0; t < 32; t++) { _mm_read_string (channels[t].name, 12, modreader); channels[t].chorus = _mm_read_UBYTE (modreader); channels[t].reverb = _mm_read_UBYTE (modreader); channels[t].pan = _mm_read_UBYTE (modreader); channels[t].status = _mm_read_UBYTE (modreader); } /* bug in Imago Orpheus ? If only channel 1 is enabled, in fact we have to enable 16 channels */ if (!channels[0].status) { for (t = 1; t < 16; t++) if (channels[t].status != 1) break; if (t == 16) for (t = 1; t < 16; t++) channels[t].status = 0; } for (t = 0; t < 32; t++) { if (channels[t].status != 2) remap[t] = of.numchn++; else remap[t] = -1; } for (t = 0; t < 32; t++) if (remap[t] != -1) { of.panning[remap[t]] = channels[t].pan; of.chanvol[remap[t]] = channels[t].status ? 0 : 64; } if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* read order list */ _mm_read_UBYTES (mh->orders, 256, modreader); if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } of.numpos = 0; for (t = 0; t < mh->ordnum; t++) if (mh->orders[t] != 0xff) of.numpos++; if (!AllocPositions (of.numpos)) return 0; for (t = u = 0; t < mh->ordnum; t++) if (mh->orders[t] != 0xff) of.positions[u++] = mh->orders[t]; /* load pattern info */ of.numtrk = of.numpat * of.numchn; if (!AllocTracks ()) return 0; if (!AllocPatterns ()) return 0; for (t = 0; t < of.numpat; t++) { SLONG size; UWORD rows; size = (SLONG) _mm_read_I_UWORD (modreader); rows = _mm_read_I_UWORD (modreader); if ((rows > 256) || (size < 4)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } of.pattrows[t] = rows; if (!IMF_ReadPattern (size - 4, rows)) return 0; for (u = 0; u < of.numchn; u++) if (!(of.tracks[track++] = IMF_ConvertTrack (&imfpat[u * 256], rows))) return 0; } /* load instruments */ if (!AllocInstruments ()) return 0; d = of.instruments; for (t = 0; t < of.numins; t++) { IMFINSTHEADER ih; memset (d->samplenumber, 0xff, INSTNOTES * sizeof (UWORD)); /* read instrument header */ _mm_read_string (ih.name, 32, modreader); d->insname = DupStr (ih.name, 31, 1); _mm_read_UBYTES (ih.what, IMFNOTECNT, modreader); _mm_fseek (modreader, 8, SEEK_CUR); _mm_read_I_UWORDS (ih.volenv, IMFENVCNT, modreader); _mm_read_I_UWORDS (ih.panenv, IMFENVCNT, modreader); _mm_read_I_UWORDS (ih.pitenv, IMFENVCNT, modreader);#define IMF_FinishLoadingEnvelope(name) \ ih.name##pts=_mm_read_UBYTE(modreader); \ ih.name##sus=_mm_read_UBYTE(modreader); \ ih.name##beg=_mm_read_UBYTE(modreader); \ ih.name##end=_mm_read_UBYTE(modreader); \ ih.name##flg=_mm_read_UBYTE(modreader); \ _mm_read_UBYTE(modreader); \ _mm_read_UBYTE(modreader); \ _mm_read_UBYTE(modreader); IMF_FinishLoadingEnvelope (vol); IMF_FinishLoadingEnvelope (pan); IMF_FinishLoadingEnvelope (pit); ih.volfade = _mm_read_I_UWORD (modreader); ih.numsmp = _mm_read_I_UWORD (modreader); _mm_read_UBYTES (id, 4, modreader); if (memcmp (id, "II10", 4)) { if (nextwav) free (nextwav); if (wh) free (wh); _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } if ((ih.numsmp > 16) || (ih.volpts > IMFENVCNT / 2) || (ih.panpts > IMFENVCNT / 2) || (ih.pitpts > IMFENVCNT / 2) || (_mm_eof (modreader))) { if (nextwav) free (nextwav); if (wh) free (wh); _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } for (u = 0; u < IMFNOTECNT; u++) d->samplenumber[u] = ih.what[u] > ih.numsmp ? 0xffff : ih.what[u] + of.numsmp; d->volfade = ih.volfade;#define IMF_ProcessEnvelope(name) \ for (u = 0; u < (IMFENVCNT >> 1); u++) { \ d->name##env[u].pos = ih.name##env[u << 1]; \ d->name##env[u].val = ih.name##env[(u << 1)+ 1]; \ } \ if (ih.name##flg&1) d->name##flg|=EF_ON; \ if (ih.name##flg&2) d->name##flg|=EF_SUSTAIN; \ if (ih.name##flg&4) d->name##flg|=EF_LOOP; \ d->name##susbeg=d->name##susend=ih.name##sus; \ d->name##beg=ih.name##beg; \ d->name##end=ih.name##end; \ d->name##pts=ih.name##pts; \ \ if ((d->name##flg&EF_ON)&&(d->name##pts<2)) \ d->name##flg&=~EF_ON; IMF_ProcessEnvelope (vol); IMF_ProcessEnvelope (pan); IMF_ProcessEnvelope (pit);#undef IMF_ProcessEnvelope if (ih.pitflg & 1) { d->pitflg &= ~EF_ON;#ifdef MIKMOD_DEBUG fputs ("\rFilter envelopes not supported yet\n", stderr);#endif } /* gather sample information */ for (u = 0; u < ih.numsmp; u++, s++) { /* allocate more room for sample information if necessary */ if (of.numsmp + u == wavcnt) { wavcnt += IMF_SMPINCR; if (!(nextwav = realloc (nextwav, wavcnt * sizeof (ULONG)))) { if (wh) free (wh); _mm_errno = MMERR_OUT_OF_MEMORY; return 0; } if (!(wh = realloc (wh, wavcnt * sizeof (IMFWAVHEADER)))) { free (nextwav); _mm_errno = MMERR_OUT_OF_MEMORY; return 0; } s = wh + (wavcnt - IMF_SMPINCR); } _mm_read_string (s->samplename, 13, modreader); _mm_read_UBYTE (modreader); _mm_read_UBYTE (modreader); _mm_read_UBYTE (modreader); s->length = _mm_read_I_ULONG (modreader); s->loopstart = _mm_read_I_ULONG (modreader); s->loopend = _mm_read_I_ULONG (modreader); s->samplerate = _mm_read_I_ULONG (modreader); s->volume = _mm_read_UBYTE (modreader) & 0x7f; s->pan = _mm_read_UBYTE (modreader); _mm_fseek (modreader, 14, SEEK_CUR); s->flags = _mm_read_UBYTE (modreader); _mm_fseek (modreader, 11, SEEK_CUR); _mm_read_UBYTES (id, 4, modreader); if (((memcmp (id, "IS10", 4)) && (memcmp (id, "IW10", 4))) || (_mm_eof (modreader))) { free (nextwav); free (wh); _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } nextwav[of.numsmp + u] = _mm_ftell (modreader); _mm_fseek (modreader, s->length, SEEK_CUR); } of.numsmp += ih.numsmp; d++; } /* sanity check */ if (!of.numsmp) { if (nextwav) free (nextwav); if (wh) free (wh); _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } /* load samples */ if (!AllocSamples ()) { free (nextwav); free (wh); return 0; } if (!AllocLinear ()) { free (nextwav); free (wh); return 0; } q = of.samples; s = wh; for (u = 0; u < of.numsmp; u++, s++, q++) { q->samplename = DupStr (s->samplename, 12, 1); q->length = s->length; q->loopstart = s->loopstart; q->loopend = s->loopend; q->volume = s->volume; q->speed = s->samplerate; if (of.flags & UF_LINEAR) q->speed = speed_to_finetune (s->samplerate << 1, u); q->panning = s->pan; q->seekpos = nextwav[u]; q->flags |= SF_SIGNED; if (s->flags & 0x1) q->flags |= SF_LOOP; if (s->flags & 0x2) q->flags |= SF_BIDI; if (s->flags & 0x8) q->flags |= SF_OWNPAN; if (s->flags & 0x4) { q->flags |= SF_16BITS; q->length >>= 1; q->loopstart >>= 1; q->loopend >>= 1; } } d = of.instruments; s = wh; for (u = 0; u < of.numins; u++, d++) { for (t = 0; t < IMFNOTECNT; t++) { if (d->samplenumber[t] >= of.numsmp) d->samplenote[t] = 255; else if (of.flags & UF_LINEAR) { int note = (int) d->samplenote[u] + noteindex[d->samplenumber[u]]; d->samplenote[u] = (note < 0) ? 0 : (note > 255 ? 255 : note); } else d->samplenote[t] = t; } } free (wh); free (nextwav); return 1;}CHAR *IMF_LoadTitle (void){ CHAR s[31]; _mm_fseek (modreader, 0, SEEK_SET); if (!_mm_read_UBYTES (s, 31, modreader)) return NULL; return (DupStr (s, 31, 1));}/*========== Loader information */MLOADER load_imf ={ NULL, "IMF", "IMF (Imago Orpheus)", IMF_Init, IMF_Test, IMF_Load, IMF_Cleanup, IMF_LoadTitle};/* ex:set ts=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -