📄 mplayer.c
字号:
dat = UniGetByte();
if (dat)
a->ffportdnspd=dat;
else
dat = a->ffportdnspd;
if (a->main.period)
if (!tick) {
a->main.period+=dat;
a->tmpperiod+=dat;
a->ownper = 1;
}
return 0;
}
/*========== Impulse Tracker effects */
static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat)
{
if (dat)
a->portspeed = dat;
/* if we don't come from another note, ignore the slide and play the note
as is */
if (!a->oldnote || !a->main.period)
return;
if ((!tick)&&(a->newsamp)){
a->main.kick=KICK_NOTE;
a->main.start=-1;
} else
a->main.kick=(a->main.kick==KICK_NOTE)?KICK_ENV:KICK_ABSENT;
if (tick) {
int dist;
/* We have to slide a->main.period towards a->wantedperiod, 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)||((a->portspeed<<2)>abs(dist)))
/* ... make tmpperiod equal tperiod */
a->tmpperiod=a->main.period=a->wantedperiod;
else
if (dist>0) {
a->tmpperiod-=a->portspeed<<2;
a->main.period-=a->portspeed<<2; /* dist>0 slide up */
} else {
a->tmpperiod+=a->portspeed<<2;
a->main.period+=a->portspeed<<2; /* dist<0 slide down */
}
} else
a->tmpperiod=a->main.period;
a->ownper=1;
}
static int DoITEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
DoITToneSlide(tick, a, UniGetByte());
return 0;
}
static void DoITVibrato(UWORD tick, MP_CONTROL *a, UBYTE dat)
{
UBYTE q;
UWORD temp=0;
if (!tick) {
if (dat&0x0f) a->vibdepth=dat&0xf;
if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
}
if (!a->main.period)
return;
q=(a->vibpos>>2)&0x1f;
switch (a->wavecontrol&3) {
case 0: /* sine */
temp=VibratoTable[q];
break;
case 1: /* square wave */
temp=255;
break;
case 2: /* ramp down */
q<<=3;
if (a->vibpos<0) q=255-q;
temp=q;
break;
case 3: /* random */
temp=getrandom(256);
break;
}
temp*=a->vibdepth;
temp>>=8;
temp<<=2;
if (a->vibpos>=0)
a->main.period=a->tmpperiod+temp;
else
a->main.period=a->tmpperiod-temp;
a->ownper=1;
a->vibpos+=a->vibspd;
}
static int DoITEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
DoITVibrato(tick, a, UniGetByte());
return 0;
}
static int DoITEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE inf, on, off;
inf = UniGetByte();
if (inf)
a->s3mtronof = inf;
else {
inf = a->s3mtronof;
if (!inf)
return 0;
}
on=(inf>>4);
off=(inf&0xf);
a->s3mtremor%=(on+off);
a->volume=(a->s3mtremor<on)?a->tmpvolume:0;
a->ownvol = 1;
a->s3mtremor++;
return 0;
}
static int DoITEffectM(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
a->main.chanvol=UniGetByte();
if (a->main.chanvol>64)
a->main.chanvol=64;
else if (a->main.chanvol<0)
a->main.chanvol=0;
return 0;
}
static int DoITEffectN(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE inf, lo, hi;
inf = UniGetByte();
if (inf)
a->chanvolslide = inf;
else
inf = a->chanvolslide;
lo=inf&0xf;
hi=inf>>4;
if (!hi)
a->main.chanvol-=lo;
else
if (!lo) {
a->main.chanvol+=hi;
} else
if (hi==0xf) {
if (!tick) a->main.chanvol-=lo;
} else
if (lo==0xf) {
if (!tick) a->main.chanvol+=hi;
}
if (a->main.chanvol<0)
a->main.chanvol=0;
else if (a->main.chanvol>64)
a->main.chanvol=64;
return 0;
}
static int DoITEffectP(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE inf, lo, hi;
SWORD pan;
inf = UniGetByte();
if (inf)
a->pansspd = inf;
else
inf = a->pansspd;
if (!mod->panflag)
return 0;
lo=inf&0xf;
hi=inf>>4;
pan=(a->main.panning==PAN_SURROUND)?PAN_CENTER:a->main.panning;
if (!hi)
pan+=lo<<2;
else
if (!lo) {
pan-=hi<<2;
} else
if (hi==0xf) {
if (!tick) pan+=lo<<2;
} else
if (lo==0xf) {
if (!tick) pan-=hi<<2;
}
a->main.panning=
(pan<PAN_LEFT)?PAN_LEFT:(pan>PAN_RIGHT?PAN_RIGHT:pan);
return 0;
}
static int DoITEffectT(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE tempo;
SWORD temp;
tempo = UniGetByte();
if (mod->patdly2)
return 0;
temp = mod->bpm;
if (tempo & 0x10)
temp += (tempo & 0x0f);
else
temp -= tempo;
mod->bpm=(temp>255)?255:(temp<1?1:temp);
return 0;
}
static int DoITEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat, q;
UWORD temp = 0; /* silence warning */
dat = UniGetByte();
if (!tick) {
if (dat&0x0f) a->vibdepth=dat&0xf;
if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
}
if (a->main.period) {
q=(a->vibpos>>2)&0x1f;
switch (a->wavecontrol&3) {
case 0: /* sine */
temp=VibratoTable[q];
break;
case 1: /* square wave */
temp=255;
break;
case 2: /* ramp down */
q<<=3;
if (a->vibpos<0) q=255-q;
temp=q;
break;
case 3: /* random */
temp=getrandom(256);
break;
}
temp*=a->vibdepth;
temp>>=8;
if (a->vibpos>=0)
a->main.period=a->tmpperiod+temp;
else
a->main.period=a->tmpperiod-temp;
a->ownper = 1;
a->vibpos+=a->vibspd;
}
return 0;
}
static int DoITEffectW(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE inf, lo, hi;
inf = UniGetByte();
if (inf)
mod->globalslide = inf;
else
inf = mod->globalslide;
lo=inf&0xf;
hi=inf>>4;
if (!lo) {
if (tick) mod->volume+=hi;
} else
if (!hi) {
if (tick) mod->volume-=lo;
} else
if (lo==0xf) {
if (!tick) mod->volume+=hi;
} else
if (hi==0xf) {
if (!tick) mod->volume-=lo;
}
if (mod->volume<0)
mod->volume=0;
else if (mod->volume>128)
mod->volume=128;
return 0;
}
static int DoITEffectY(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat, q;
SLONG temp = 0; /* silence warning */
dat=UniGetByte();
if (!tick) {
if (dat&0x0f) a->panbdepth=(dat&0xf);
if (dat&0xf0) a->panbspd=(dat&0xf0)>>4;
}
if (mod->panflag) {
q=a->panbpos;
switch (a->panbwave) {
case 0: /* sine */
temp=PanbrelloTable[q];
break;
case 1: /* square wave */
temp=(q<0x80)?64:0;
break;
case 2: /* ramp down */
q<<=3;
temp=q;
break;
case 3: /* random */
temp=getrandom(256);
break;
}
temp*=a->panbdepth;
temp=(temp/8)+mod->panning[channel];
a->main.panning=
(temp<PAN_LEFT)?PAN_LEFT:(temp>PAN_RIGHT?PAN_RIGHT:temp);
a->panbpos+=a->panbspd;
}
return 0;
}
static void DoNNAEffects(MODULE *, MP_CONTROL *, UBYTE);
/* Impulse/Scream Tracker Sxx effects.
All Sxx effects share the same memory space. */
static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat, inf, c;
dat = UniGetByte();
inf=dat&0xf;
c=dat>>4;
if (!dat) {
c=a->sseffect;
inf=a->ssdata;
} else {
a->sseffect=c;
a->ssdata=inf;
}
switch (c) {
case SS_GLISSANDO: /* S1x set glissando voice */
DoEEffects(tick, flags, a, mod, channel, 0x30|inf);
break;
case SS_FINETUNE: /* S2x set finetune */
DoEEffects(tick, flags, a, mod, channel, 0x50|inf);
break;
case SS_VIBWAVE: /* S3x set vibrato waveform */
DoEEffects(tick, flags, a, mod, channel, 0x40|inf);
break;
case SS_TREMWAVE: /* S4x set tremolo waveform */
DoEEffects(tick, flags, a, mod, channel, 0x70|inf);
break;
case SS_PANWAVE: /* S5x panbrello */
a->panbwave=inf;
break;
case SS_FRAMEDELAY: /* S6x delay x number of frames (patdly) */
DoEEffects(tick, flags, a, mod, channel, 0xe0|inf);
break;
case SS_S7EFFECTS: /* S7x instrument / NNA commands */
DoNNAEffects(mod, a, inf);
break;
case SS_PANNING: /* S8x set panning position */
DoEEffects(tick, flags, a, mod, channel, 0x80 | inf);
break;
case SS_SURROUND: /* S9x set surround sound */
if (mod->panflag)
a->main.panning = mod->panning[channel] = PAN_SURROUND;
break;
case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */
if (!tick) {
a->hioffset=inf<<16;
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;
}
break;
case SS_PATLOOP: /* SBx pattern loop */
DoEEffects(tick, flags, a, mod, channel, 0x60|inf);
break;
case SS_NOTECUT: /* SCx notecut */
if (!inf) inf = 1;
DoEEffects(tick, flags, a, mod, channel, 0xC0|inf);
break;
case SS_NOTEDELAY: /* SDx notedelay */
DoEEffects(tick, flags, a, mod, channel, 0xD0|inf);
break;
case SS_PATDELAY: /* SEx patterndelay */
DoEEffects(tick, flags, a, mod, channel, 0xE0|inf);
break;
}
return 0;
}
/*========== Impulse Tracker Volume/Pan Column effects */
/*
* All volume/pan column effects share the same memory space.
*/
static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE c, inf;
c = UniGetByte();
inf = UniGetByte();
if ((!c)&&(!inf)) {
c=a->voleffect;
inf=a->voldata;
} else {
a->voleffect=c;
a->voldata=inf;
}
if (c)
switch (c) {
case VOL_VOLUME:
if (tick) break;
if (inf>64) inf=64;
a->tmpvolume=inf;
break;
case VOL_PANNING:
if (mod->panflag)
a->main.panning=inf;
break;
case VOL_VOLSLIDE:
DoS3MVolSlide(tick, flags, a, inf);
return 1;
case VOL_PITCHSLIDEDN:
if (a->main.period)
DoS3MSlideDn(tick, a, inf);
break;
case VOL_PITCHSLIDEUP:
if (a->main.period)
DoS3MSlideUp(tick, a, inf);
break;
case VOL_PORTAMENTO:
DoITToneSlide(tick, a, inf);
break;
case VOL_VIBRATO:
DoITVibrato(tick, a, inf);
break;
}
return 0;
}
/*========== UltraTracker effects */
static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UWORD offset=UniGetWord();
if (offset)
a->ultoffset=offset;
a->main.start=a->ultoffset<<2;
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;
}
/*========== OctaMED effects */
static int DoMEDSpeed(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UWORD speed=UniGetWord();
mod->bpm=speed;
return 0;
}
static int DoMEDEffectF1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -