From ca19c631d99feffd1b4932ddf115bfd0f5133dfe Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 18 Jan 2026 19:04:49 -0500 Subject: [PATCH] add compatibility flag for vol slide reset on targ et --- src/engine/playback.cpp | 23 ++++++++++++++++------- src/engine/song.cpp | 3 +++ src/engine/song.h | 1 + src/gui/compatFlags.cpp | 6 ++++++ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index eeb3509d0..2e1f934a8 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -2232,24 +2232,34 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { } else if (chan[i].volSpeed<0) { chan[i].volume=MIN(preSpeedVol,chan[i].volSpeedTarget); } - chan[i].volSpeed=0; - chan[i].volSpeedTarget=-1; + // COMPAT FLAG: don't stop volume slides after reaching target + // - when enabled, we don't reset the volume speed + if (!song.compatFlags.noVolSlideReset) { + chan[i].volSpeed=0; + chan[i].volSpeedTarget=-1; + } dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8)); dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,0)); } } // stop sliding if we reach maximum/minimum volume - // there isn't a compat flag for this yet... sorry... if (chan[i].volume>chan[i].volMax) { chan[i].volume=chan[i].volMax; - chan[i].volSpeed=0; - chan[i].volSpeedTarget=-1; + // COMPAT FLAG: don't stop volume slides after reaching target + if (!song.compatFlags.noVolSlideReset) { + chan[i].volSpeed=0; + chan[i].volSpeedTarget=-1; + } dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8)); dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,0)); } else if (chan[i].volume<0) { - chan[i].volSpeed=0; + // COMPAT FLAG: don't stop volume slides after reaching target + if (!song.compatFlags.noVolSlideReset) { + chan[i].volSpeed=0; + chan[i].volSpeedTarget=-1; + } dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,0)); // COMPAT FLAG: legacy volume slides // - sets volume to max once a vol slide down has finished (thus setting volume to volMax+1) @@ -2259,7 +2269,6 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { } else { chan[i].volume=0; } - chan[i].volSpeedTarget=-1; dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8)); } else { diff --git a/src/engine/song.cpp b/src/engine/song.cpp index 91ec6b440..5cb472999 100644 --- a/src/engine/song.cpp +++ b/src/engine/song.cpp @@ -1165,6 +1165,7 @@ void DivCompatFlags::setDefaults() { oldAlwaysSetVolume=false; oldSampleOffset=false; oldCenterRate=true; + noVolSlideReset=false; } bool DivCompatFlags::areDefaults() { @@ -1250,6 +1251,7 @@ bool DivCompatFlags::readData(SafeReader& reader) { CHECK_AND_LOAD_BOOL(oldAlwaysSetVolume); CHECK_AND_LOAD_BOOL(oldSampleOffset); CHECK_AND_LOAD_BOOL(oldCenterRate); + CHECK_AND_LOAD_BOOL(noVolSlideReset); return true; } @@ -1324,6 +1326,7 @@ void DivCompatFlags::putData(SafeWriter* w) { CHECK_AND_STORE_BOOL(oldAlwaysSetVolume); CHECK_AND_STORE_BOOL(oldSampleOffset); CHECK_AND_STORE_BOOL(oldCenterRate); + CHECK_AND_STORE_BOOL(noVolSlideReset); String data=c.toString(); w->write("CFLG",4); diff --git a/src/engine/song.h b/src/engine/song.h index 828e52304..f40fdba37 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -255,6 +255,7 @@ struct DivCompatFlags { bool oldSampleOffset; // new flags as of dev240 bool oldCenterRate; + bool noVolSlideReset; void setDefaults(); bool areDefaults(); diff --git a/src/gui/compatFlags.cpp b/src/gui/compatFlags.cpp index 1b05e0063..5403394f1 100644 --- a/src/gui/compatFlags.cpp +++ b/src/gui/compatFlags.cpp @@ -426,6 +426,12 @@ void FurnaceGUI::drawCompatFlags() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip(_("when enabled, the slide effect will not be disabled after it reaches its target.")); } + if (ImGui::Checkbox(_("Don't reset volume slides after reaching target"),&e->song.compatFlags.noVolSlideReset)) { + MARK_MODIFIED; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip(_("when enabled, volume slide speeds will not be reset after reaching target or bounds.")); + } if (ImGui::Checkbox(_("Continuous vibrato"),&e->song.compatFlags.continuousVibrato)) { MARK_MODIFIED; }