📄 mplayer.c
字号:
UBYTE dat; dat = UniGetByte(); if (!tick) { if (!dat && (flags & UF_ARPMEM)) dat=a->arpmem; else a->arpmem=dat; } if (a->main.period) DoArpeggio(tick, flags, a, 0); return 0;}static int DoPTEffect1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat = UniGetByte(); if (!tick && dat) a->slidespeed = (UWORD)dat << 2; if (a->main.period) if (tick) a->tmpperiod -= a->slidespeed; return 0;}static int DoPTEffect2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat = UniGetByte(); if (!tick && dat) a->slidespeed = (UWORD)dat << 2; if (a->main.period) if (tick) a->tmpperiod += a->slidespeed; return 0;}static void DoToneSlide(UWORD tick, MP_CONTROL *a){ if (!a->main.fadevol) a->main.kick = (a->main.kick == KICK_NOTE)? KICK_NOTE : KICK_KEYOFF; else a->main.kick = (a->main.kick == KICK_NOTE)? KICK_ENV : KICK_ABSENT; if (tick != 0) { int dist; /* We have to slide a->main.period towards a->wantedperiod, so compute the difference between those two values */ dist=a->main.period-a->wantedperiod; /* if they are equal or if portamentospeed is too big ...*/ if (dist == 0 || a->portspeed > abs(dist)) /* ...make tmpperiod equal tperiod */ a->tmpperiod=a->main.period=a->wantedperiod; else if (dist>0) { a->tmpperiod-=a->portspeed; a->main.period-=a->portspeed; /* dist>0, slide up */ } else { a->tmpperiod+=a->portspeed; a->main.period+=a->portspeed; /* dist<0, slide down */ } } else a->tmpperiod=a->main.period; a->ownper = 1;}static int DoPTEffect3(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if ((!tick)&&(dat)) a->portspeed=(UWORD)dat<<2; if (a->main.period) DoToneSlide(tick, a); return 0;}static void DoVibrato(UWORD tick, MP_CONTROL *a){ UBYTE q; UWORD temp = 0; /* silence warning */ if (!tick) return; q=(a->vibpos>>2)&0x1f; switch (a->wavecontrol&3) { case 0: /* sine */ temp=VibratoTable[q]; break; case 1: /* ramp down */ q<<=3; if (a->vibpos<0) q=255-q; temp=q; break; case 2: /* square wave */ temp=255; break; case 3: /* random wave */ temp=getrandom(256); break; } temp*=a->vibdepth; temp>>=7;temp<<=2; if (a->vibpos>=0) a->main.period=a->tmpperiod+temp; else a->main.period=a->tmpperiod-temp; a->ownper = 1; if (tick != 0) a->vibpos+=a->vibspd;}static int DoPTEffect4(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if (!tick) { if (dat&0x0f) a->vibdepth=dat&0xf; if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; } if (a->main.period) DoVibrato(tick, a); return 0;}static void DoVolSlide(MP_CONTROL *a, UBYTE dat){ if (dat&0xf) { a->tmpvolume-=(dat&0x0f); if (a->tmpvolume<0) a->tmpvolume=0; } else { a->tmpvolume+=(dat>>4); if (a->tmpvolume>64) a->tmpvolume=64; }}static int DoPTEffect5(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if (a->main.period) DoToneSlide(tick, a); if (tick) DoVolSlide(a, dat); return 0;}/* DoPTEffect6 after DoPTEffectA */static int DoPTEffect7(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; UBYTE q; UWORD temp = 0; /* silence warning */ dat=UniGetByte(); if (!tick) { if (dat&0x0f) a->trmdepth=dat&0xf; if (dat&0xf0) a->trmspd=(dat&0xf0)>>2; } if (a->main.period) { q=(a->trmpos>>2)&0x1f; switch ((a->wavecontrol>>4)&3) { case 0: /* sine */ temp=VibratoTable[q]; break; case 1: /* ramp down */ q<<=3; if (a->trmpos<0) q=255-q; temp=q; break; case 2: /* square wave */ temp=255; break; case 3: /* random wave */ temp=getrandom(256); break; } temp*=a->trmdepth; temp>>=6; if (a->trmpos>=0) { a->volume=a->tmpvolume+temp; if (a->volume>64) a->volume=64; } else { a->volume=a->tmpvolume-temp; if (a->volume<0) a->volume=0; } a->ownvol = 1; if (tick) a->trmpos+=a->trmspd; } return 0;}static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat = UniGetByte(); if (mod->panflag) a->main.panning = mod->panning[channel] = dat; return 0;}static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if (!tick) { if (dat) a->soffset=(UWORD)dat<<8; a->main.start=a->hioffset|a->soffset; if ((a->main.s)&&(a->main.start>a->main.s->length)) a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? a->main.s->loopstart:a->main.s->length; } return 0;}static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if (tick) DoVolSlide(a, dat); return 0;}static int DoPTEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ if (a->main.period) DoVibrato(tick, a); DoPTEffectA(tick, flags, a, mod, channel); return 0;}static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if (tick || mod->patdly2) return 0; /* Vincent Voois uses a nasty trick in "Universal Bolero" */ if (dat == mod->sngpos && mod->patbrk == mod->patpos) return 0; if (!mod->loop && !mod->patbrk && (dat < mod->sngpos || (mod->sngpos == (mod->numpos - 1) && !mod->patbrk) || (dat == mod->sngpos && (flags & UF_NOWRAP)) )) { /* if we don't loop, better not to skip the end of the pattern, after all... so: mod->patbrk=0; */ mod->posjmp=3; } else { /* if we were fading, adjust... */ if (mod->sngpos == (mod->numpos-1)) mod->volume=mod->initvolume>128?128:mod->initvolume; mod->sngpos=dat; mod->posjmp=2; mod->patpos=0; } return 0;}static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if (tick) return 0; if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */ else if (dat>64) dat=64; a->tmpvolume=dat; return 0;}static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if ((tick)||(mod->patdly2)) return 0; if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&& (dat>mod->pattrows[mod->positions[mod->sngpos]])) dat=mod->pattrows[mod->positions[mod->sngpos]]; mod->patbrk=dat; if (!mod->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 ((mod->sngpos==mod->numpos-1)&&(dat)&&((mod->loop)|| (mod->positions[mod->sngpos]==(mod->numpat-1) && !(flags&UF_NOWRAP)))) { mod->sngpos=0; mod->posjmp=2; } else mod->posjmp=3; } return 0;}static void DoEEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel, UBYTE dat){ UBYTE nib = dat & 0xf; switch (dat>>4) { case 0x0: /* hardware filter toggle, not supported */ break; case 0x1: /* fineslide up */ if (a->main.period) if (!tick) a->tmpperiod-=(nib<<2); break; case 0x2: /* fineslide dn */ if (a->main.period) if (!tick) a->tmpperiod+=(nib<<2); break; case 0x3: /* glissando ctrl */ a->glissando=nib; break; case 0x4: /* set vibrato waveform */ a->wavecontrol&=0xf0; a->wavecontrol|=nib; break; case 0x5: /* set finetune */ if (a->main.period) { if (flags&UF_XMPERIODS) a->speed=nib+128; else a->speed=finetune[nib]; a->tmpperiod=GetPeriod(flags, (UWORD)a->main.note<<1,a->speed); } break; case 0x6: /* set patternloop */ if (tick) break; if (nib) { /* set reppos or repcnt ? */ /* set repcnt, so check if repcnt already is set, which means we are already looping */ if (a->pat_repcnt) a->pat_repcnt--; /* already looping, decrease counter */ else {#if 0 /* this would make walker.xm, shipped with Xsoundtracker, play correctly, but it's better to remain compatible with FT2 */ if ((!(flags&UF_NOWRAP))||(a->pat_reppos!=POS_NONE))#endif a->pat_repcnt=nib; /* not yet looping, so set repcnt */ } if (a->pat_repcnt) { /* jump to reppos if repcnt>0 */ if (a->pat_reppos==POS_NONE) a->pat_reppos=mod->patpos-1; if (a->pat_reppos==-1) { mod->pat_repcrazy=1; mod->patpos=0; } else mod->patpos=a->pat_reppos; } else a->pat_reppos=POS_NONE; } else a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */ break; case 0x7: /* set tremolo waveform */ a->wavecontrol&=0x0f; a->wavecontrol|=nib<<4; break; case 0x8: /* set panning */ if (mod->panflag) { if (nib<=8) nib<<=4; else nib*=17; a->main.panning=mod->panning[channel]=nib; } break; case 0x9: /* retrig note */ /* do not retrigger on tick 0, until we are emulating FT2 and effect data is zero */ if (!tick && !((flags & UF_FT2QUIRKS) && (!nib))) break; /* only retrigger if data nibble > 0, or if tick 0 (FT2 compat) */ if (nib || !tick) { if (!a->retrig) { /* when retrig counter reaches 0, reset counter and restart the sample */ if (a->main.period) a->main.kick=KICK_NOTE; a->retrig=nib; } a->retrig--; /* countdown */ } break; case 0xa: /* fine volume slide up */ if (tick) break; a->tmpvolume+=nib; if (a->tmpvolume>64) a->tmpvolume=64; break; case 0xb: /* fine volume slide dn */ if (tick) break; a->tmpvolume-=nib; if (a->tmpvolume<0)a->tmpvolume=0; break; case 0xc: /* cut note */ /* When tick reaches the cut-note value, turn the volume to zero (just like on the amiga) */ if (tick>=nib) a->tmpvolume=0; /* just turn the volume down */ break; case 0xd: /* note delay */ /* delay the start of the sample until tick==nib */ if (!tick) a->main.notedelay=nib; else if (a->main.notedelay) a->main.notedelay--; break; case 0xe: /* pattern delay */ if (!tick) if (!mod->patdly2) mod->patdly=nib+1; /* only once, when tick=0 */ break; case 0xf: /* invert loop, not supported */ break; }}static int DoPTEffectE(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ DoEEffects(tick, flags, a, mod, channel, UniGetByte()); return 0;}static int DoPTEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE dat; dat=UniGetByte(); if (tick||mod->patdly2) return 0; if (mod->extspd&&(dat>=mod->bpmlimit)) mod->bpm=dat; else if (dat) { mod->sngspd=(dat>=mod->bpmlimit)?mod->bpmlimit-1:dat; mod->vbtick=0; } return 0;}/*========== Scream Tracker effects */static int DoS3MEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ UBYTE speed; speed = UniGetByte(); if (tick || mod->patdly2) return 0; if (speed > 128) speed -= 128; if (speed) { mod->sngspd = speed; mod->vbtick = 0; } return 0;}static void DoS3MVolSlide(UWORD tick, UWORD flags, MP_CONTROL *a, UBYTE inf){ UBYTE lo, hi; if (inf) a->s3mvolslide=inf; else inf=a->s3mvolslide; lo=inf&0xf; hi=inf>>4; if (!lo) { if ((tick)||(flags&UF_S3MSLIDES)) a->tmpvolume+=hi; } else if (!hi) { if ((tick)||(flags&UF_S3MSLIDES)) a->tmpvolume-=lo; } else if (lo==0xf) { if (!tick) a->tmpvolume+=(hi?hi:0xf); } else if (hi==0xf) { if (!tick) a->tmpvolume-=(lo?lo:0xf); } else return; if (a->tmpvolume<0) a->tmpvolume=0; else if (a->tmpvolume>64) a->tmpvolume=64;}static int DoS3MEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel){ DoS3MVolSlide(tick, flags, a, UniGetByte()); return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -