add effects for quick legato

This commit is contained in:
tildearrow 2024-03-16 19:41:08 -05:00
parent beacfcf849
commit 415a8297fe
5 changed files with 60 additions and 4 deletions

View file

@ -105,8 +105,14 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
return "E4xx: Set vibrato range";
case 0xe5:
return "E5xx: Set pitch (80: center)";
case 0xe6:
return "E6xy: Quick legato (x: time (0-7 up; 8-F down); y: semitones)";
case 0xe7:
return "E7xx: Macro release";
case 0xe8:
return "E8xy: Quick legato up (x: time; y: semitones)";
case 0xe9:
return "E9xy: Quick legato down (x: time; y: semitones)";
case 0xea:
return "EAxx: Legato";
case 0xeb:

View file

@ -100,7 +100,7 @@ enum DivMIDIModes {
struct DivChannelState {
std::vector<DivDelayedCommand> delayed;
int note, oldNote, lastIns, pitch, portaSpeed, portaNote;
int volume, volSpeed, cut, rowDelay, volMax;
int volume, volSpeed, cut, legatoDelay, legatoTarget, rowDelay, volMax;
int delayOrder, delayRow, retrigSpeed, retrigTick;
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine;
int tremoloDepth, tremoloRate, tremoloPos;
@ -123,6 +123,8 @@ struct DivChannelState {
volume(0x7f00),
volSpeed(0),
cut(-1),
legatoDelay(-1),
legatoTarget(0),
rowDelay(0),
volMax(0),
delayOrder(0),

View file

@ -956,6 +956,21 @@ void DivEngine::processRow(int i, bool afterDelay) {
dispatchCmd(DivCommand(DIV_CMD_PITCH,i,chan[i].pitch+(((chan[i].vibratoDepth*vibTable[chan[i].vibratoPos]*chan[i].vibratoFine)>>4)/15)));
dispatchCmd(DivCommand(DIV_CMD_HINT_PITCH,i,chan[i].pitch));
break;
case 0xe6: // Delayed legato
// why does this have to follow FamiTracker verbatim
// couldn't you do better?
if ((effectVal&15)!=0) {
chan[i].legatoDelay=(((effectVal&0xf0)>>4)&7)+1;
if (effectVal&128) {
chan[i].legatoTarget=-(effectVal&15);
} else {
chan[i].legatoTarget=(effectVal&15);
}
} else {
chan[i].legatoDelay=-1;
chan[i].legatoTarget=0;
}
break;
case 0xe7: // delayed macro release
// "Bruh"
if (effectVal>0 && (song.delayBehavior==2 || effectVal<nextSpeed)) {
@ -963,6 +978,25 @@ void DivEngine::processRow(int i, bool afterDelay) {
chan[i].cutType=2;
}
break;
case 0xe8: // delayed legato up
// see? you COULD do better!
if ((effectVal&15)!=0) {
chan[i].legatoDelay=((effectVal&0xf0)>>4)+1;
chan[i].legatoTarget=(effectVal&15);
} else {
chan[i].legatoDelay=-1;
chan[i].legatoTarget=0;
}
break;
case 0xe9: // delayed legato down
if ((effectVal&15)!=0) {
chan[i].legatoDelay=((effectVal&0xf0)>>4)+1;
chan[i].legatoTarget=-(effectVal&15);
} else {
chan[i].legatoDelay=-1;
chan[i].legatoTarget=0;
}
break;
case 0xea: // legato mode
chan[i].legato=effectVal;
break;
@ -1539,6 +1573,15 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
break;
}
}
if (chan[i].legatoDelay>0) {
if (--chan[i].legatoDelay<1) {
chan[i].note+=chan[i].legatoTarget;
dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note));
dispatchCmd(DivCommand(DIV_CMD_HINT_LEGATO,i,chan[i].note));
chan[i].legatoDelay=-1;
chan[i].legatoTarget=0;
}
}
if (!song.noSlidesOnFirstTick || !firstTick) {
if ((chan[i].keyOn || chan[i].keyOff) && chan[i].portaSpeed>0) {
if (dispatchCmd(DivCommand(DIV_CMD_NOTE_PORTA,i,chan[i].portaSpeed*(song.linearPitch==2?song.pitchSlideSpeed:1),chan[i].portaNote))==2 && chan[i].portaStop && song.targetResetsSlides) {