📄 mod.c
字号:
if (mp.vbtick) a->tmpperiod -= a->slidespeed; break; case UNI_PTEFFECT2: dat = UniGetByte (); if ((!mp.vbtick) && (dat)) a->slidespeed = (UWORD) dat << 2; if (a->period) if (mp.vbtick) a->tmpperiod += a->slidespeed; break; case UNI_PTEFFECT3: dat = UniGetByte (); if ((!mp.vbtick) && (dat)) a->portspeed = (UWORD) dat << 2; if (a->period) { if (!a->fadevol) a->kick = (a->kick == KICK_NOTE) ? KICK_NOTE : KICK_KEYOFF; else a->kick = (a->kick == KICK_NOTE) ? KICK_ENV : KICK_ABSENT; DoToneSlide (); a->ownper = 1; } break; case UNI_PTEFFECT4: case UNI_XMEFFECT4: dat = UniGetByte (); if (!mp.vbtick) { if (dat & 0x0f) a->vibdepth = dat & 0xf; if (dat & 0xf0) a->vibspd = (dat & 0xf0) >> 2; } else if (a->period) { DoVibrato (); a->ownper = 1; } break; case UNI_PTEFFECT5: dat = UniGetByte (); if (a->period) { if (!a->fadevol) a->kick = (a->kick == KICK_NOTE) ? KICK_NOTE : KICK_KEYOFF; else a->kick = (a->kick == KICK_NOTE) ? KICK_ENV : KICK_ABSENT; DoToneSlide (); a->ownper = 1; } DoVolSlide (dat); break; case UNI_PTEFFECT6: dat = UniGetByte (); if ((a->period) && (mp.vbtick)) { DoVibrato (); a->ownper = 1; } DoVolSlide (dat); break; case UNI_PTEFFECT7: dat = UniGetByte (); if (!mp.vbtick) { if (dat & 0x0f) a->trmdepth = dat & 0xf; if (dat & 0xf0) a->trmspd = (dat & 0xf0) >> 2; } if (a->period) { DoTremolo (); a->ownvol = 1; } break; case UNI_PTEFFECT8: dat = UniGetByte (); a->panning = pf->panning[mp.channel] = dat; break; case UNI_PTEFFECT9: dat = UniGetByte (); if (!mp.vbtick) { if (dat) a->soffset = (UWORD) dat << 8; a->start = a->hioffset | a->soffset; if ((a->s) && (a->start > a->s->length)) a->start = a->s->flags & (SF_LOOP | SF_BIDI) ? a->s->loopstart : a->s->length; } break; case UNI_PTEFFECTA: DoVolSlide (UniGetByte ()); break; case UNI_PTEFFECTB: dat = UniGetByte (); if ((mp.vbtick) || (mp.patdly2)) break; /* Vincent Voois uses a nasty trick in "Universal Bolero" */ if (dat == mp.sngpos && mp.patbrk == mp.patpos) break; if ((!mp.patbrk) && ((dat < mp.sngpos) || ((mp.sngpos == pf->numpos - 1) && (!mp.patbrk)) || ((dat == mp.sngpos) && (pf->flags & UF_NOWRAP)))) { /* if we don't loop, better not to skip the end of the pattern, after all... so: mp.patbrk=0; */ mp.posjmp = 3; } else { /* if we were fading, adjust... */ if (mp.sngpos == (pf->numpos - 1)) mp.volume = pf->initvolume > 128 ? 128 : pf->initvolume; mp.sngpos = dat; mp.posjmp = 2; mp.patpos = 0; } break; case UNI_PTEFFECTC: dat = UniGetByte (); if (mp.vbtick) break; if (dat == (UBYTE) - 1) a->anote = dat = 0; /* note cut */ else if (dat > 64) dat = 64; a->tmpvolume = dat; break; case UNI_PTEFFECTD: dat = UniGetByte (); if ((mp.vbtick) || (mp.patdly2)) break; if ((pf->positions[mp.sngpos] != 255) && (dat > pf->pattrows[pf->positions[mp.sngpos]])) dat = pf->pattrows[pf->positions[mp.sngpos]]; mp.patbrk = dat; if (!mp.posjmp) { /* don't ask me to explain this code - it makes * backwards.s3m and children.xm (heretic's version) play * correctly, among others. Take that for granted, or write * the page of comments yourself... you might need some * aspirin - Miod */ if ((mp.sngpos == pf->numpos - 1) && (dat) && ((pf->positions[mp.sngpos] == (pf->numpat - 1) && (pf->flags & UF_NOWRAP)))) { /* printf("%d -- Pattern 0!\n", __LINE__); */ mp.sngpos = 0; mp.posjmp = 2; } else mp.posjmp = 3; } break; case UNI_PTEFFECTE: DoEEffects (UniGetByte ()); break; case UNI_PTEFFECTF: dat = UniGetByte (); if (mp.vbtick || mp.patdly2) break; if (dat > 0x20) mp.newbpm = dat; else if (dat) { mp.sngspd = (dat > 32) ? 32 : dat; mp.vbtick = 0; } break; case UNI_S3MEFFECTA: DoS3MSpeed (UniGetByte ()); break; case UNI_S3MEFFECTD: DoS3MVolSlide (UniGetByte ()); break; case UNI_S3MEFFECTE: dat = UniGetByte (); if (a->period) DoS3MSlideDn (dat); break; case UNI_S3MEFFECTF: dat = UniGetByte (); if (a->period) DoS3MSlideUp (dat); break; case UNI_S3MEFFECTI: DoS3MTremor (UniGetByte ()); a->ownvol = 1; break; case UNI_S3MEFFECTQ: dat = UniGetByte (); if (a->period) DoS3MRetrig (dat); break; case UNI_S3MEFFECTR: dat = UniGetByte (); if (!mp.vbtick) { if (dat & 0x0f) a->trmdepth = dat & 0xf; if (dat & 0xf0) a->trmspd = (dat & 0xf0) >> 2; } DoS3MTremolo (); a->ownvol = 1; break; case UNI_S3MEFFECTT: DoS3MTempo (UniGetByte ()); break; case UNI_S3MEFFECTU: dat = UniGetByte (); if (!mp.vbtick) { if (dat & 0x0f) a->vibdepth = dat & 0xf; if (dat & 0xf0) a->vibspd = (dat & 0xf0) >> 2; } else if (a->period) { DoS3MFineVibrato (); a->ownper = 1; } break; case UNI_KEYOFF: a->keyoff |= KEY_OFF; if ((!(a->volflg & EF_ON)) || (a->volflg & EF_LOOP)) a->keyoff = KEY_KILL; break; case UNI_KEYFADE: dat = UniGetByte (); if ((mp.vbtick >= dat) || (mp.vbtick == mp.sngspd - 1)) { a->keyoff = KEY_KILL; if (!(a->volflg & EF_ON)) a->fadevol = 0; } break; case UNI_VOLEFFECTS: DoVolEffects (UniGetByte ()); break; case UNI_XMEFFECTA: DoXMVolSlide (UniGetByte ()); break; case UNI_XMEFFECTE1: /* XM fineslide up */ if (mp.vbtick) break; dat = UniGetByte (); if (!mp.vbtick) { if (dat) a->fportupspd = dat; if (a->period) a->tmpperiod -= (a->fportupspd << 2); } break; case UNI_XMEFFECTE2: /* XM fineslide dn */ if (mp.vbtick) break; dat = UniGetByte (); if (!mp.vbtick) { if (dat) a->fportdnspd = dat; if (a->period) a->tmpperiod += (a->fportdnspd << 2); } break; case UNI_XMEFFECTEA: /* fine volume slide up */ if (mp.vbtick) break; dat = UniGetByte (); if (dat) a->fslideupspd = dat; a->tmpvolume += a->fslideupspd; if (a->tmpvolume > 64) a->tmpvolume = 64; break; case UNI_XMEFFECTEB: /* fine volume slide dn */ if (mp.vbtick) break; dat = UniGetByte (); if (dat) a->fslidednspd = dat; a->tmpvolume -= a->fslidednspd; if (a->tmpvolume < 0) a->tmpvolume = 0; break; case UNI_XMEFFECTG: mp.volume = UniGetByte () << 1; if (mp.volume > 128) mp.volume = 128; break; case UNI_XMEFFECTH: DoXMGlobalSlide (UniGetByte ()); break; case UNI_XMEFFECTL: dat = UniGetByte (); if ((!mp.vbtick) && (a->i)) { UWORD points; INSTRUMENT *i = a->i; MP_VOICE *aout; if ((aout = a->slave)) { if (aout->venv.env) { points = i->volenv[i->volpts - 1].pos; aout->venv.p = aout->venv.env[(dat > points) ? points : dat].pos; } if (aout->penv.env) { points = i->panenv[i->panpts - 1].pos; aout->penv.p = aout->penv.env[(dat > points) ? points : dat].pos; } } } break; case UNI_XMEFFECTP: dat = UniGetByte (); DoXMPanSlide (dat); break; case UNI_XMEFFECTX1: if (mp.vbtick) break; dat = UniGetByte (); if (dat) a->ffportupspd = dat; else dat = a->ffportupspd; if (a->period) { DoXMExtraFineSlideUp (dat); a->ownper = 1; } break; case UNI_XMEFFECTX2: if (mp.vbtick) break; dat = UniGetByte (); if (dat) a->ffportdnspd = dat; else dat = a->ffportdnspd; if (a->period) { DoXMExtraFineSlideDown (dat); a->ownper = 1; } break; case UNI_ITEFFECTG: dat = UniGetByte (); if (dat) { a->portspeed = dat; } if (a->period) { if ((!mp.vbtick) && (a->newsamp)) { a->kick = KICK_NOTE; a->start = -1; } else a->kick = (a->kick == KICK_NOTE) ? KICK_ENV : KICK_ABSENT; DoITToneSlide (); a->ownper = 1; } break; case UNI_ITEFFECTH: /* IT vibrato */ dat = UniGetByte (); if (!mp.vbtick) { if (dat & 0x0f) a->vibdepth = dat & 0xf; if (dat & 0xf0) a->vibspd = (dat & 0xf0) >> 2; } if (a->period) { DoITVibrato (); a->ownper = 1; } break; case UNI_ITEFFECTI: /* IT tremor */ DoITTremor (UniGetByte ()); a->ownvol = 1; break; case UNI_ITEFFECTM: a->chanvol = UniGetByte (); if (a->chanvol > 64) a->chanvol = 64; else if (a->chanvol < 0) a->chanvol = 0; break; case UNI_ITEFFECTN: /* slide / fineslide channel volume */ DoITChanVolSlide (UniGetByte ()); break; case UNI_ITEFFECTP: /* slide / fineslide channel panning */ dat = UniGetByte (); DoITPanSlide (dat); break; case UNI_ITEFFECTT: /* slide / fineslide tempo */ DoITTempo (UniGetByte ()); break; case UNI_ITEFFECTU: /* fine vibrato */ dat = UniGetByte (); if (!mp.vbtick) { if (dat & 0x0f) a->vibdepth = dat & 0xf; if (dat & 0xf0) a->vibspd = (dat & 0xf0) >> 2; } if (a->period) { DoITFineVibrato (); a->ownper = 1; } break; case UNI_ITEFFECTW: /* slide / fineslide global volume */ DoITGlobalSlide (UniGetByte ()); break; case UNI_ITEFFECTY: /* panbrello */ dat = UniGetByte (); if (!mp.vbtick) { if (dat & 0x0f) a->panbdepth = (dat & 0xf); if (dat & 0xf0) a->panbspd = (dat & 0xf0) >> 4; } DoITPanbrello (); break; case UNI_ITEFFECTS0: DoSSEffects (UniGetByte ()); break; case UNI_ITEFFECTZ: /* FIXME not yet implemented */ UniSkipOpcode (UNI_ITEFFECTZ); break; case UNI_ULTEFFECT9: DoULTSampleOffset (); break; case UNI_MEDSPEED: DoMEDSpeed (); break; case UNI_MEDEFFECTF1: DoEEffects (0x90 | (mp.sngspd / 2)); break; case UNI_MEDEFFECTF2: DoEEffects (0xd0 | (mp.sngspd / 2)); break; case UNI_MEDEFFECTF3: DoEEffects (0x90 | (mp.sngspd / 3)); break; /* case UNI_NOTE: */ /* case UNI_INSTRUMENT: */ default: a->sliding = oldsliding; UniSkipOpcode (c); break; } }}static void DoNNAEffects (UBYTE dat){ int t; MP_VOICE *aout; dat &= 0xf; aout = (a->slave) ? a->slave : NULL; switch (dat) { case 0x0: /* past note cut */ for (t = 0; t < MOD_NUM_VOICES; t++) if (mp.voice[t].master == a) mp.voice[t].fadevol = 0; break; case 0x1: /* past note off */ for (t = 0; t < MOD_NUM_VOICES; t++) if (mp.voice[t].master == a) { mp.voice[t].keyoff |= KEY_OFF; if ((!(mp.voice[t].venv.flg & EF_ON)) || (mp.voice[t].venv.flg & EF_LOOP)) mp.voice[t].keyoff = KEY_KILL; } break; case 0x2: /* past note fade */ for (t = 0; t < MOD_NUM_VOICES; t++) if (mp.voice[t].master == a) mp.voice[t].keyoff |= KEY_FADE; break; case 0x3: /* set NNA note cut */ a->nna = (a->nna & ~NNA_MASK) | NNA_CUT; break; case 0x4: /* set NNA note continue */ a->nna = (a->nna & ~NNA_MASK) | NNA_CONTINUE; break; case 0x5: /* set NNA note off */ a->nna = (a->nna & ~NNA_MASK) | NNA_OFF; break; case 0x6: /* set NNA note fade */ a->nna = (a->nna & ~NNA_MASK) | NNA_FADE; break; case 0x7: /* disable volume envelope */ if (aout) aout->volflg &= ~EF_ON; break; case 0x8: /* enable volume envelope */ if (aout) aout->volflg |= EF_ON; break; case 0x9: /* disable panning envelope */ if (aout) aout->panflg &= ~EF_ON; break; case 0xa: /* enable panning envelope */ if (aout) aout->panflg |= EF_ON; break; case 0xb: /* disable pitch envelope */ if (aout) aout->pitflg &= ~EF_ON; break; case 0xc: /* enable pitch envelope */ if (aout) aout->pitflg |= EF_ON; break; }}static void pt_UpdateVoices (){ SWORD envpan, envvol, envpit; UWORD playperiod; SLONG vibval, vibdpt; ULONG tmpvol; BOOL kick_voice; MP_VOICE *aout; INSTRUMENT *i; SAMPLE *s; mp.totalchn = mp.realchn = 0; for (mp.channel = 0; mp.channel < MOD_NUM_VOICES; mp.channel++) { aout = &mp.voice[mp.channel]; i = aout->i; s = aout->s; if ((!s) || (!s->length)) continue; if (aout->period < 14 || aout->period > 50000) { Voice_Stop(mp.channel); continue; } kick_voice = 0; if ((aout->kick == KICK_NOTE) || (aout->kick == KICK_KEYOFF)) { kick_voice = 1; aout->fadevol = 32768; aout->aswppos = 0; } /* check for a dead note (fadevol=0) */ if (!aout->fadevol || kick_voice) Voice_Stop (mp.channel); if (i && ((aout->kick == KICK_NOTE) || (aout->kick == KICK_ENV))) { StartEnvelope (&aout->venv, aout->volflg, i->volpts, i->volsusbeg, i->volsusend, i->volbeg, i->volend, i->volenv, aout->keyoff); StartEnvelope (&aout->penv, aout->panflg, i->panpts, i->pansusbeg,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -