From d63f3d311b48548f218a370bbb71e862a1f72d91 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 17 Mar 2022 16:37:49 -0500 Subject: [PATCH] fix arpeggio not resetting note to base on 0000 --- src/engine/engine.h | 10 ++++++---- src/engine/fileOps.cpp | 14 ++++++++++---- src/engine/playback.cpp | 7 +++++++ src/engine/song.h | 4 +++- src/gui/gui.cpp | 4 ++++ 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 80e2514d..28e2a870 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -37,8 +37,8 @@ warnings+=(String("\n")+x); \ } -#define DIV_VERSION "dev68" -#define DIV_ENGINE_VERSION 68 +#define DIV_VERSION "dev69" +#define DIV_ENGINE_VERSION 69 // for imports #define DIV_VERSION_MOD 0xff01 @@ -78,7 +78,8 @@ struct DivChannelState { int vibratoDepth, vibratoRate, vibratoPos, vibratoDir, vibratoFine; int tremoloDepth, tremoloRate, tremoloPos; unsigned char arp, arpStage, arpTicks; - bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff, arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit; + bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff; + bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp; DivChannelState(): note(-1), @@ -119,7 +120,8 @@ struct DivChannelState { inPorta(false), scheduledSlideReset(false), shorthandPorta(false), - noteOnInhibit(false) {} + noteOnInhibit(false), + resetArp(false) {} }; struct DivNoteEvent { diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index a47be934..f6038f45 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -143,6 +143,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.brokenDACMode=true; ds.oneTickCut=false; ds.newInsTriggersInPorta=true; + ds.arp0Reset=true; // 1.1 compat flags if (ds.version>24) { @@ -818,6 +819,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { if (ds.version<66) { ds.newInsTriggersInPorta=false; } + if (ds.version<69) { + ds.arp0Reset=false; + } ds.isDMF=false; reader.readS(); // reserved @@ -1009,7 +1013,11 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } else { reader.readC(); } - for (int i=0; i<1; i++) reader.readC(); + if (ds.version>=69) { + ds.arp0Reset=reader.readC(); + } else { + reader.readC(); + } } else { for (int i=0; i<20; i++) reader.readC(); } @@ -1828,9 +1836,7 @@ SafeWriter* DivEngine::saveFur() { w->writeC(song.brokenDACMode); w->writeC(song.oneTickCut); w->writeC(song.newInsTriggersInPorta); - for (int i=0; i<1; i++) { - w->writeC(0); - } + w->writeC(song.arp0Reset); ptrSeek=w->tell(); // instrument pointers (we'll seek here later) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 965f2853..f1fb7fc4 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -909,6 +909,9 @@ void DivEngine::processRow(int i, bool afterDelay) { break; case 0x00: // arpeggio chan[i].arp=effectVal; + if (chan[i].arp==0 && song.arp0Reset) { + chan[i].resetArp=true; + } break; case 0x0c: // retrigger if (effectVal!=0) { @@ -1335,6 +1338,10 @@ bool DivEngine::nextTick(bool noAccum) { dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,i)); } } + if (chan[i].resetArp) { + dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note)); + chan[i].resetArp=false; + } if (chan[i].arp!=0 && !chan[i].arpYield && chan[i].portaSpeed<1) { if (--chan[i].arpTicks<1) { chan[i].arpTicks=song.arpLen; diff --git a/src/engine/song.h b/src/engine/song.h index 6799909d..7495b01c 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -300,6 +300,7 @@ struct DivSong { bool brokenDACMode; bool oneTickCut; bool newInsTriggersInPorta; + bool arp0Reset; DivOrders orders; std::vector ins; @@ -371,7 +372,8 @@ struct DivSong { continuousVibrato(false), brokenDACMode(false), oneTickCut(false), - newInsTriggersInPorta(true) { + newInsTriggersInPorta(true), + arp0Reset(true) { for (int i=0; i<32; i++) { system[i]=DIV_SYSTEM_NULL; systemVol[i]=64; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 11fedfed..e006f01f 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2197,6 +2197,10 @@ void FurnaceGUI::drawCompatFlags() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("behavior changed in 0.6"); } + ImGui::Checkbox("Reset note to base on arpeggio stop",&e->song.arp0Reset); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("behavior changed in 0.6"); + } } if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_COMPAT_FLAGS; ImGui::End();