📄 load_it.c
字号:
if (mh->flags & 8) of.flags |= (UF_XMPERIODS | UF_LINEAR); if ((mh->cwt >= 0x106) && (mh->flags & 16)) old_effect = 1; else old_effect = 0; /* set panning positions */ for (t = 0; t < 64; t++) { mh->pantable[t] &= 0x7f; if (mh->pantable[t] < 64) of.panning[t] = mh->pantable[t] << 2; else if (mh->pantable[t] == 64) of.panning[t] = 255; else if (mh->pantable[t] == 100) of.panning[t] = PAN_SURROUND; else if (mh->pantable[t] == 127) of.panning[t] = PAN_CENTER; else { _mm_errno = MMERR_LOADING_HEADER; return 0; } } /* set channel volumes */ memcpy (of.chanvol, mh->voltable, 64); /* read the order data */ if (!AllocPositions (mh->ordnum)) return 0; if (!(origpositions = _mm_calloc (mh->ordnum, sizeof (UWORD)))) return 0; for (t = 0; t < mh->ordnum; t++) { origpositions[t] = _mm_read_UBYTE (modreader); if ((origpositions[t] > mh->patnum) && (origpositions[t] < 254)) origpositions[t] = 255; } if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } poslookupcnt = mh->ordnum; S3MIT_CreateOrders (curious); if (!(paraptr = (ULONG *) _mm_malloc ((mh->insnum + mh->smpnum + of.numpat) * sizeof (ULONG)))) return 0; /* read the instrument, sample, and pattern parapointers */ _mm_read_I_ULONGS (paraptr, mh->insnum + mh->smpnum + of.numpat, modreader); if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* Check for and load midi information for resonant filters */ if (mh->cmwt >= 0x216) { if (mh->special & 8) { IT_LoadMidiConfiguration (modreader); if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } } else IT_LoadMidiConfiguration (NULL); filters = 1; } /* Check for and load song comment */ if ((mh->special & 1) && (mh->cwt >= 0x104) && (mh->msglength)) { _mm_fseek (modreader, (long) (mh->msgoffset), SEEK_SET); if (!ReadComment (mh->msglength)) return 0; } if (!(mh->flags & 4)) of.numins = of.numsmp; if (!AllocSamples ()) return 0; if (!AllocLinear ()) return 0; /* Load all samples */ q = of.samples; for (t = 0; t < mh->smpnum; t++) { ITSAMPLE s; /* seek to sample position */ _mm_fseek (modreader, (long) (paraptr[mh->insnum + t] + 4), SEEK_SET); /* load sample info */ _mm_read_string (s.filename, 12, modreader); s.zerobyte = _mm_read_UBYTE (modreader); s.globvol = _mm_read_UBYTE (modreader); s.flag = _mm_read_UBYTE (modreader); s.volume = _mm_read_UBYTE (modreader); _mm_read_string (s.sampname, 26, modreader); s.convert = _mm_read_UBYTE (modreader); s.panning = _mm_read_UBYTE (modreader); s.length = _mm_read_I_ULONG (modreader); s.loopbeg = _mm_read_I_ULONG (modreader); s.loopend = _mm_read_I_ULONG (modreader); s.c5spd = _mm_read_I_ULONG (modreader); s.susbegin = _mm_read_I_ULONG (modreader); s.susend = _mm_read_I_ULONG (modreader); s.sampoffset = _mm_read_I_ULONG (modreader); s.vibspeed = _mm_read_UBYTE (modreader); s.vibdepth = _mm_read_UBYTE (modreader); s.vibrate = _mm_read_UBYTE (modreader); s.vibwave = _mm_read_UBYTE (modreader); /* Some IT files have bogues loopbeg/loopend if looping is not used by * a sample. */ if (!(s.flag & 80)) s.loopbeg = s.loopend = 0; /* Generate an error if c5spd is > 512k, or samplelength > 256 megs (nothing would EVER be that high) */ if (_mm_eof (modreader) || (s.c5spd > 0x7ffffL) || (s.length > 0xfffffffUL) || (s.loopbeg > 0xfffffffUL) || (s.loopend > 0xfffffffUL)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } q->samplename = DupStr (s.sampname, 26, 0); q->speed = s.c5spd / 2; q->panning = ((s.panning & 127) == 64) ? 255 : (s.panning & 127) << 2; q->length = s.length; q->loopstart = s.loopbeg; q->loopend = s.loopend; q->volume = s.volume; q->globvol = s.globvol; q->seekpos = s.sampoffset; /* Convert speed to XM linear finetune */ if (of.flags & UF_LINEAR) q->speed = speed_to_finetune (s.c5spd, t); if (s.panning & 128) q->flags |= SF_OWNPAN; if (s.vibrate) { q->vibflags |= AV_IT; q->vibtype = s.vibwave; q->vibsweep = s.vibrate * 2; q->vibdepth = s.vibdepth; q->vibrate = s.vibspeed; } if (s.flag & 2) q->flags |= SF_16BITS; if ((s.flag & 8) && (mh->cwt >= 0x214)) { q->flags |= SF_ITPACKED; compressed = 1; } if (s.flag & 16) q->flags |= SF_LOOP; if (s.flag & 64) q->flags |= SF_BIDI; if (mh->cwt >= 0x200) { if (s.convert & 1) q->flags |= SF_SIGNED; if (s.convert & 4) q->flags |= SF_DELTA; } q++; } /* Load instruments if instrument mode flag enabled */ if (mh->flags & 4) { if (!AllocInstruments ()) return 0; d = of.instruments; of.flags |= UF_NNA | UF_INST; for (t = 0; t < mh->insnum; t++) { ITINSTHEADER ih; /* seek to instrument position */ _mm_fseek (modreader, paraptr[t] + 4, SEEK_SET); /* load instrument info */ _mm_read_string (ih.filename, 12, modreader); ih.zerobyte = _mm_read_UBYTE (modreader); if (mh->cwt < 0x200) { /* load IT 1.xx inst header */ ih.volflg = _mm_read_UBYTE (modreader); ih.volbeg = _mm_read_UBYTE (modreader); ih.volend = _mm_read_UBYTE (modreader); ih.volsusbeg = _mm_read_UBYTE (modreader); ih.volsusend = _mm_read_UBYTE (modreader); _mm_read_I_UWORD (modreader); ih.fadeout = _mm_read_I_UWORD (modreader); ih.nna = _mm_read_UBYTE (modreader); ih.dnc = _mm_read_UBYTE (modreader); } else { /* Read IT200+ header */ ih.nna = _mm_read_UBYTE (modreader); ih.dct = _mm_read_UBYTE (modreader); ih.dca = _mm_read_UBYTE (modreader); ih.fadeout = _mm_read_I_UWORD (modreader); ih.ppsep = _mm_read_UBYTE (modreader); ih.ppcenter = _mm_read_UBYTE (modreader); ih.globvol = _mm_read_UBYTE (modreader); ih.chanpan = _mm_read_UBYTE (modreader); ih.rvolvar = _mm_read_UBYTE (modreader); ih.rpanvar = _mm_read_UBYTE (modreader); } ih.trkvers = _mm_read_I_UWORD (modreader); ih.numsmp = _mm_read_UBYTE (modreader); _mm_read_UBYTE (modreader); _mm_read_string (ih.name, 26, modreader); _mm_read_UBYTES (ih.blank01, 6, modreader); _mm_read_I_UWORDS (ih.samptable, ITNOTECNT, modreader); if (mh->cwt < 0x200) { /* load IT 1xx volume envelope */ _mm_read_UBYTES (ih.volenv, 200, modreader); for (lp = 0; lp < ITENVCNT; lp++) { ih.oldvoltick[lp] = _mm_read_UBYTE (modreader); ih.volnode[lp] = _mm_read_UBYTE (modreader); } } else { /* load IT 2xx volume, pan and pitch envelopes */#define IT_LoadEnvelope(name,type) \ ih.name##flg =_mm_read_UBYTE(modreader); \ ih.name##pts =_mm_read_UBYTE(modreader); \ ih.name##beg =_mm_read_UBYTE(modreader); \ ih.name##end =_mm_read_UBYTE(modreader); \ ih.name##susbeg=_mm_read_UBYTE(modreader); \ ih.name##susend=_mm_read_UBYTE(modreader); \ for(lp=0;lp<ITENVCNT;lp++) { \ ih.name##node[lp]=_mm_read_##type(modreader); \ ih.name##tick[lp]=_mm_read_I_UWORD(modreader); \ } \ _mm_read_UBYTE(modreader); IT_LoadEnvelope (vol, UBYTE); IT_LoadEnvelope (pan, SBYTE); IT_LoadEnvelope (pit, SBYTE);#undef IT_LoadEnvelope } if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } d->volflg |= EF_VOLENV; d->insname = DupStr (ih.name, 26, 0); d->nnatype = ih.nna; if (mh->cwt < 0x200) { d->volfade = ih.fadeout << 6; if (ih.dnc) { d->dct = DCT_NOTE; d->dca = DCA_CUT; } if (ih.volflg & 1) d->volflg |= EF_ON; if (ih.volflg & 2) d->volflg |= EF_LOOP; if (ih.volflg & 4) d->volflg |= EF_SUSTAIN; /* XM conversion of IT envelope Array */ d->volbeg = ih.volbeg; d->volend = ih.volend; d->volsusbeg = ih.volsusbeg; d->volsusend = ih.volsusend; if (ih.volflg & 1) { for (u = 0; u < ITENVCNT; u++) if (ih.oldvoltick[d->volpts] != 0xff) { d->volenv[d->volpts].val = (ih.volnode[d->volpts] << 2); d->volenv[d->volpts].pos = ih.oldvoltick[d->volpts]; d->volpts++; } else break; } } else { d->panning = ((ih.chanpan & 127) == 64) ? 255 : (ih.chanpan & 127) << 2; if (!(ih.chanpan & 128)) d->flags |= IF_OWNPAN; if (!(ih.ppsep & 128)) { d->pitpansep = ih.ppsep << 2; d->pitpancenter = ih.ppcenter; d->flags |= IF_PITCHPAN; } d->globvol = ih.globvol >> 1; d->volfade = ih.fadeout << 5; d->dct = ih.dct; d->dca = ih.dca; if (mh->cwt >= 0x204) { d->rvolvar = ih.rvolvar; d->rpanvar = ih.rpanvar; }#define IT_ProcessEnvelope(name) \ if(ih.name##flg&1) d->name##flg|=EF_ON; \ if(ih.name##flg&2) d->name##flg|=EF_LOOP; \ if(ih.name##flg&4) d->name##flg|=EF_SUSTAIN; \ d->name##pts=ih.name##pts; \ d->name##beg=ih.name##beg; \ d->name##end=ih.name##end; \ d->name##susbeg=ih.name##susbeg; \ d->name##susend=ih.name##susend; \ \ for(u=0;u<ih.name##pts;u++) \ d->name##env[u].pos=ih.name##tick[u]; \ \ if((d->name##flg&EF_ON)&&(d->name##pts<2)) \ d->name##flg&=~EF_ON; IT_ProcessEnvelope (vol); for (u = 0; u < ih.volpts; u++) d->volenv[u].val = (ih.volnode[u] << 2); IT_ProcessEnvelope (pan); for (u = 0; u < ih.panpts; u++) d->panenv[u].val = ih.pannode[u] == 32 ? 255 : (ih.pannode[u] + 32) << 2; IT_ProcessEnvelope (pit); for (u = 0; u < ih.pitpts; u++) d->pitenv[u].val = ih.pitnode[u] + 32;#undef IT_ProcessEnvelope if (ih.pitflg & 0x80) { /* filter envelopes not supported yet */ d->pitflg &= ~EF_ON; ih.pitpts = ih.pitbeg = ih.pitend = 0;#ifdef MIKMOD_DEBUG { static int warn = 0; if (!warn) fputs ("\rFilter envelopes not supported yet\n", stderr); warn = 1; }#endif } d->volpts = ih.volpts; d->volbeg = ih.volbeg; d->volend = ih.volend; d->volsusbeg = ih.volsusbeg; d->volsusend = ih.volsusend; for (u = 0; u < ih.volpts; u++) { d->volenv[u].val = (ih.volnode[u] << 2); d->volenv[u].pos = ih.voltick[u]; } d->panpts = ih.panpts; d->panbeg = ih.panbeg; d->panend = ih.panend; d->pansusbeg = ih.pansusbeg; d->pansusend = ih.pansusend; for (u = 0; u < ih.panpts; u++) { d->panenv[u].val = ih.pannode[u] == 32 ? 255 : (ih.pannode[u] + 32) << 2; d->panenv[u].pos = ih.pantick[u]; } d->pitpts = ih.pitpts; d->pitbeg = ih.pitbeg; d->pitend = ih.pitend; d->pitsusbeg = ih.pitsusbeg; d->pitsusend = ih.pitsusend; for (u = 0; u < ih.pitpts; u++) { d->pitenv[u].val = ih.pitnode[u] + 32; d->pitenv[u].pos = ih.pittick[u]; } } for (u = 0; u < ITNOTECNT; u++) { d->samplenote[u] = (ih.samptable[u] & 255); d->samplenumber[u] = (ih.samptable[u] >> 8) ? ((ih.samptable[u] >> 8) - 1) : 0xffff; if (d->samplenumber[u] >= of.numsmp) d->samplenote[u] = 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); } } d++; } } else if (of.flags & UF_LINEAR) { if (!AllocInstruments ()) return 0; d = of.instruments; of.flags |= UF_INST; for (t = 0; t < mh->smpnum; t++, d++) for (u = 0; u < ITNOTECNT; u++) { if (d->samplenumber[u] >= of.numsmp) d->samplenote[u] = 255; else { int note = (int) d->samplenote[u] + noteindex[d->samplenumber[u]]; d->samplenote[u] = (note < 0) ? 0 : (note > 255 ? 255 : note); } } } /* Figure out how many channels this song actually uses */ of.numchn = 0; memset (remap, -1, 64 * sizeof (UBYTE)); for (t = 0; t < of.numpat; t++) { UWORD packlen; /* seek to pattern position */ if (paraptr[mh->insnum + mh->smpnum + t]) { /* 0 -> empty 64 row pattern */ _mm_fseek (modreader, ((long) paraptr[mh->insnum + mh->smpnum + t]), SEEK_SET); _mm_read_I_UWORD (modreader); /* read pattern length (# of rows) Impulse Tracker never creates patterns with less than 32 rows, but some other trackers do, so we only check for more than 256 rows */ packlen = _mm_read_I_UWORD (modreader); if (packlen > 256) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } _mm_read_I_ULONG (modreader); if (IT_GetNumChannels (packlen)) return 0; } } /* give each of them a different number */ for (t = 0; t < 64; t++) if (!remap[t]) remap[t] = of.numchn++; of.numtrk = of.numpat * of.numchn; if (of.numvoices) if (of.numvoices < of.numchn) of.numvoices = of.numchn; if (!AllocPatterns ()) return 0; if (!AllocTracks ()) return 0; for (t = 0; t < of.numpat; t++) { UWORD packlen; /* seek to pattern position */ if (!paraptr[mh->insnum + mh->smpnum + t]) { /* 0 -> empty 64 row pattern */ of.pattrows[t] = 64; for (u = 0; u < of.numchn; u++) { int k; UniReset (); for (k = 0; k < 64; k++) UniNewline (); of.tracks[numtrk++] = UniDup (); } } else { _mm_fseek (modreader, ((long) paraptr[mh->insnum + mh->smpnum + t]), SEEK_SET); packlen = _mm_read_I_UWORD (modreader); of.pattrows[t] = _mm_read_I_UWORD (modreader); _mm_read_I_ULONG (modreader); if (!IT_ReadPattern (of.pattrows[t])) return 0; } } return 1;}CHAR *IT_LoadTitle (void){ CHAR s[26]; _mm_fseek (modreader, 4, SEEK_SET); if (!_mm_read_UBYTES (s, 26, modreader)) return NULL; return (DupStr (s, 26, 0));}/*========== Loader information */MLOADER load_it ={ NULL, "IT", "IT (Impulse Tracker)", IT_Init, IT_Test, IT_Load, IT_Cleanup, IT_LoadTitle};/* ex:set ts=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -