📄 mod.c
字号:
DoXMGlobalSlide (UBYTE inf){ if (mp.vbtick) { if (inf) mp.globalslide = inf; else inf = mp.globalslide; if (inf & 0xf0) inf &= 0xf0; mp.volume = mp.volume + ((inf >> 4) - (inf & 0xf)) * 2; if (mp.volume < 0) mp.volume = 0; else if (mp.volume > 128) mp.volume = 128; }}static void DoXMPanSlide (UBYTE inf){ UBYTE lo, hi; SWORD pan; if (inf) a->pansspd = inf; else inf = a->pansspd; if (!mp.vbtick) return; lo = inf & 0xf; hi = inf >> 4; /* slide right has absolute priority */ if (hi) lo = 0; pan = ((a->panning == PAN_SURROUND) ? PAN_CENTER : a->panning) + hi - lo; a->panning = (pan < PAN_LEFT) ? PAN_LEFT : (pan > PAN_RIGHT ? PAN_RIGHT : pan);}static void DoXMExtraFineSlideUp (UBYTE inf){ if (!mp.vbtick) { a->period -= inf; a->tmpperiod -= inf; }}static void DoXMExtraFineSlideDown (UBYTE inf){ if (!mp.vbtick) { a->period += inf; a->tmpperiod += inf; }}/*========== Impulse Tracker effects */static void DoITChanVolSlide (UBYTE inf){ UBYTE lo, hi; if (inf) a->chanvolslide = inf; inf = a->chanvolslide; lo = inf & 0xf; hi = inf >> 4; if (!hi) a->chanvol -= lo; else if (!lo) { a->chanvol += hi; } else if (hi == 0xf) { if (!mp.vbtick) a->chanvol -= lo; } else if (lo == 0xf) { if (!mp.vbtick) a->chanvol += hi; } if (a->chanvol < 0) a->chanvol = 0; if (a->chanvol > 64) a->chanvol = 64;}static void DoITGlobalSlide (UBYTE inf){ UBYTE lo, hi; if (inf) mp.globalslide = inf; inf = mp.globalslide; lo = inf & 0xf; hi = inf >> 4; if (!lo) { if (mp.vbtick) mp.volume += hi; } else if (!hi) { if (mp.vbtick) mp.volume -= lo; } else if (lo == 0xf) { if (!mp.vbtick) mp.volume += hi; } else if (hi == 0xf) { if (!mp.vbtick) mp.volume -= lo; } if (mp.volume < 0) mp.volume = 0; if (mp.volume > 128) mp.volume = 128;}static void DoITPanSlide (UBYTE inf){ UBYTE lo, hi; SWORD pan; if (inf) a->pansspd = inf; else inf = a->pansspd; lo = inf & 0xf; hi = inf >> 4; pan = (a->panning == PAN_SURROUND) ? PAN_CENTER : a->panning; if (!hi) pan += lo << 2; else if (!lo) { pan -= hi << 2; } else if (hi == 0xf) { if (!mp.vbtick) pan += lo << 2; } else if (lo == 0xf) { if (!mp.vbtick) pan -= hi << 2; } a->panning = /*pf->panning[mp.channel]= */ (pan < PAN_LEFT) ? PAN_LEFT : (pan > PAN_RIGHT ? PAN_RIGHT : pan);}static void DoITTempo (UBYTE tempo){ SWORD temp = mp.newbpm; if (mp.patdly2) return; if (tempo & 0x10) temp += (tempo & 0x0f); else temp -= tempo; mp.newbpm = (temp > 255) ? 255 : (temp < 1 ? 1 : temp);}static void DoITVibrato (void){ UBYTE q; UWORD temp = 0; 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->period = a->tmpperiod + temp; else a->period = a->tmpperiod - temp; a->vibpos += a->vibspd;}static void DoITFineVibrato (void){ UBYTE q; UWORD temp = 0; 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->period = a->tmpperiod + temp; else a->period = a->tmpperiod - temp; a->vibpos += a->vibspd;}static void DoITTremor (UBYTE inf){ UBYTE on, off; if (inf) a->s3mtronof = inf; else { inf = a->s3mtronof; if (!inf) return; } if (!mp.vbtick) return; on = (inf >> 4); off = (inf & 0xf); a->s3mtremor %= (on + off); a->volume = (a->s3mtremor < on) ? a->tmpvolume : 0; a->s3mtremor++;}static void DoITPanbrello (void){ UBYTE q; SLONG temp = 0; 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 */ if (a->panbpos >= a->panbspd) { a->panbpos = 0; temp = getrandom (256); } } temp *= a->panbdepth; temp = (temp / 8) + pf->panning[mp.channel]; a->panning = (temp < PAN_LEFT) ? PAN_LEFT : (temp > PAN_RIGHT ? PAN_RIGHT : temp); a->panbpos += a->panbspd;}static void DoITToneSlide (void){ /* if we don't come from another note, ignore the slide and play the note as is */ if (!a->oldnote) return; if (mp.vbtick) { int dist; /* We have to slide a->period towards a->wantedperiod, compute the difference between those two values */ dist = a->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->period = a->wantedperiod; else if (dist > 0) { a->tmpperiod -= a->portspeed << 2; a->period -= a->portspeed << 2; /* dist>0 slide up */ } else { a->tmpperiod += a->portspeed << 2; a->period += a->portspeed << 2; /* dist<0 slide down */ } } else a->tmpperiod = a->period;}static void DoNNAEffects (UBYTE dat);/* Impulse/Scream Tracker Sxx effects. All Sxx effects share the same memory space. */static void DoSSEffects (UBYTE dat){ UBYTE inf, c; 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 (0x30 | inf); break; case SS_FINETUNE: /* S2x set finetune */ DoEEffects (0x50 | inf); break; case SS_VIBWAVE: /* S3x set vibrato waveform */ DoEEffects (0x40 | inf); break; case SS_TREMWAVE: /* S4x set tremolo waveform */ DoEEffects (0x70 | inf); break; case SS_PANWAVE: /* S5x panbrello */ a->panbwave = inf; break; case SS_FRAMEDELAY: /* S6x delay x number of frames (patdly) */ DoEEffects (0xe0 | inf); break; case SS_S7EFFECTS: /* S7x instrument / NNA commands */ DoNNAEffects (inf); break; case SS_PANNING: /* S8x set panning position */ DoEEffects (0x80 | inf); break; case SS_SURROUND: /* S9x set surround sound */ a->panning = pf->panning[mp.channel] = PAN_SURROUND; break; case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */ if (!mp.vbtick) { a->hioffset = inf << 16; 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 SS_PATLOOP: /* SBx pattern loop */ DoEEffects (0x60 | inf); break; case SS_NOTECUT: /* SCx notecut */ DoEEffects (0xC0 | inf); break; case SS_NOTEDELAY: /* SDx notedelay */ DoEEffects (0xD0 | inf); break; case SS_PATDELAY: /* SEx patterndelay */ DoEEffects (0xE0 | inf); break; }}/* Impulse Tracker Volume/Pan Column effects. All volume/pan column effects share the same memory space. */static void DoVolEffects (UBYTE c){ UBYTE 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 (mp.vbtick) break; if (inf > 64) inf = 64; a->tmpvolume = inf; break; case VOL_PANNING: a->panning = /*pf->panning[mp.channel]= */ inf; break; case VOL_VOLSLIDE: DoS3MVolSlide (inf); break; case VOL_PITCHSLIDEDN: if (a->period) DoS3MSlideDn (inf); break; case VOL_PITCHSLIDEUP: if (a->period) DoS3MSlideUp (inf); break; case VOL_PORTAMENTO: if (inf) a->slidespeed = inf; 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 VOL_VIBRATO: if (!mp.vbtick) { if (inf & 0x0f) a->vibdepth = inf & 0xf; if (inf & 0xf0) a->vibspd = (inf & 0xf0) >> 2; } if (a->period) { DoITVibrato (); a->ownper = 1; } break; }}/*========== UltraTracker effects */static void DoULTSampleOffset (void){ UWORD offset = UniGetWord (); if (offset) a->ultoffset = offset; a->start = a->ultoffset << 2; if ((a->s) && (a->start > a->s->length)) a->start = a->s->flags & (SF_LOOP | SF_BIDI) ? a->s->loopstart : a->s->length;}/*========== OctaMED effects */static void DoMEDSpeed (void){ UWORD speed = UniGetWord (); mp.newbpm = speed;}/*========== General player functions */static void pt_playeffects (void){ UBYTE dat, c, oldc = 0; while ((c = UniGetByte ())) { int oldsliding = a->sliding; a->sliding = 0; /* libunimod doesn't *quite* do Ultimate Soundtracker portas correctly */ if (strcmp(of.modtype, "Ultimate Soundtracker") == 0) { if (c == 5 && oldc == 4) { oldc = 5; a->sliding = oldsliding; UniSkipOpcode (c); continue; } oldc = c; if (c == 3 || c == 4) c++; } switch (c) { case UNI_PTEFFECT0: dat = UniGetByte (); if (!mp.vbtick) { if ((!dat) && (pf->flags & UF_ARPMEM)) dat = a->arpmem; else a->arpmem = dat; } if (a->period) DoArpeggio (a->arpmem); break; case UNI_PTEFFECT1: dat = UniGetByte (); if ((!mp.vbtick) && (dat)) a->slidespeed = (UWORD) dat << 2; if (a->period)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -