From 10aaf7f0cb9dcddad32a444125cef56224e17abd Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 21 Aug 2022 19:57:01 -0500 Subject: [PATCH 1/5] YM2612: #580 --- src/engine/platform/genesisext.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index 1f320dd34..dfd7d514c 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -561,6 +561,11 @@ void DivPlatformGenesisExt::forceIns() { opChan[i].freqChanged=true; } } + if (extMode && softPCM && chan[7].active) { // CSM + chan[7].insChanged=true; + chan[7].freqChanged=true; + chan[7].keyOn=true; + } } void* DivPlatformGenesisExt::getChanState(int ch) { From b223bc80de9f16fc137f033e7ed50d0037cebbe1 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 21 Aug 2022 20:06:01 -0500 Subject: [PATCH 2/5] YM2612: #581 --- src/engine/platform/genesis.cpp | 36 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 143a90fe8..7dde9790e 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -263,19 +263,37 @@ void DivPlatformGenesis::tick(bool sysTick) { } } - if (chan[i].std.arp.had) { - if (!chan[i].inPorta) { - if (chan[i].std.arp.mode) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11); - } else { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11); + if (i>=5 && chan[i].furnaceDac) { + if (chan[i].std.arp.had) { + if (!chan[i].inPorta) { + if (chan[i].std.arp.mode) { + chan[i].baseFreq=parent->calcBaseFreq(1,1,chan[i].std.arp.val,false); + } else { + chan[i].baseFreq=parent->calcBaseFreq(1,1,chan[i].note+(signed char)chan[i].std.arp.val,false); + } + } + chan[i].freqChanged=true; + } else { + if (chan[i].std.arp.mode && chan[i].std.arp.finished) { + chan[i].baseFreq=parent->calcBaseFreq(1,1,chan[i].note,false); + chan[i].freqChanged=true; } } - chan[i].freqChanged=true; } else { - if (chan[i].std.arp.mode && chan[i].std.arp.finished) { - chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11); + if (chan[i].std.arp.had) { + if (!chan[i].inPorta) { + if (chan[i].std.arp.mode) { + chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].std.arp.val,11); + } else { + chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note+(signed char)chan[i].std.arp.val,11); + } + } chan[i].freqChanged=true; + } else { + if (chan[i].std.arp.mode && chan[i].std.arp.finished) { + chan[i].baseFreq=NOTE_FNUM_BLOCK(chan[i].note,11); + chan[i].freqChanged=true; + } } } From 38afdd3378bcac8878c41d6442f6b54caf50c458 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 21 Aug 2022 23:56:58 -0500 Subject: [PATCH 3/5] dev110 - add cut/delay effect policy compat flag INCOMPLETE!!! --- src/engine/engine.h | 4 ++-- src/engine/fileOps.cpp | 15 +++++++++++++-- src/engine/playback.cpp | 5 ++++- src/engine/song.h | 6 ++++++ src/gui/compatFlags.cpp | 20 ++++++++++++++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index c433def8e..d379540c5 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -46,8 +46,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "dev109" -#define DIV_ENGINE_VERSION 109 +#define DIV_VERSION "dev110" +#define DIV_ENGINE_VERSION 110 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index df32f0553..e64e02a04 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -176,6 +176,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.e1e2StopOnSameNote=true; ds.brokenPortaArp=false; ds.snNoLowPeriods=true; + ds.delayBehavior=0; // 1.1 compat flags if (ds.version>24) { @@ -1067,6 +1068,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { if (ds.version<108) { ds.snNoLowPeriods=true; } + if (ds.version<110) { + ds.delayBehavior=1; + } ds.isDMF=false; reader.readS(); // reserved @@ -1484,7 +1488,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } else { reader.readC(); } - for (int i=0; i<6; i++) { + if (ds.version>=110) { + ds.delayBehavior=reader.readC(); + } else { + reader.readC(); + } + for (int i=0; i<5; i++) { reader.readC(); } } @@ -1917,6 +1926,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) { ds.noSlidesOnFirstTick=true; ds.rowResetsArpPos=true; ds.ignoreJumpAtEnd=false; + ds.delayBehavior=0; int insCount=31; bool bypassLimits=false; @@ -3729,7 +3739,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) { w->writeC(song.e1e2StopOnSameNote); w->writeC(song.brokenPortaArp); w->writeC(song.snNoLowPeriods); - for (int i=0; i<6; i++) { + w->writeC(song.delayBehavior); + for (int i=0; i<5; i++) { w->writeC(0); } diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 63203ab54..fbd9e8db3 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -361,7 +361,9 @@ void DivEngine::processRow(int i, bool afterDelay) { break; case 0xed: // delay if (effectVal!=0) { - if (effectVal<=nextSpeed) { + bool comparison=(song.delayBehavior==1)?(effectVal<=nextSpeed):(effectVal%d",effectVal,nextSpeed); chan[i].delayLocked=false; } } diff --git a/src/engine/song.h b/src/engine/song.h index 30f5ef245..83509efbf 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -463,6 +463,11 @@ struct DivSong { // 1: fake reset on loop // 2: don't do anything on loop unsigned char loopModality; + // cut/delay effect behavior + // 0: strict (don't allow value higher than or equal to speed) + // 1: broken (don't allow value higher than speed) + // 2: lax (allow value higher than speed) + unsigned char delayBehavior; bool properNoiseLayout; bool waveDutyIsVol; bool resetMacroOnPorta; @@ -565,6 +570,7 @@ struct DivSong { linearPitch(2), pitchSlideSpeed(4), loopModality(0), + delayBehavior(2), properNoiseLayout(true), waveDutyIsVol(false), resetMacroOnPorta(false), diff --git a/src/gui/compatFlags.cpp b/src/gui/compatFlags.cpp index e6d0aed85..74d493e7f 100644 --- a/src/gui/compatFlags.cpp +++ b/src/gui/compatFlags.cpp @@ -193,6 +193,26 @@ void FurnaceGUI::drawCompatFlags() { ImGui::SetTooltip("select to not reset channels on loop."); } + ImGui::Text("Cut/delay effect policy:"); + if (ImGui::RadioButton("Strict",e->song.delayBehavior==0)) { + e->song.delayBehavior=0; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("only when time is less than speed (like DefleMask/ProTracker)"); + } + if (ImGui::RadioButton("Strict (old)",e->song.delayBehavior==1)) { + e->song.delayBehavior=1; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("only when time is less than or equal to speed (original buggy behavior)"); + } + if (ImGui::RadioButton("Lax",e->song.delayBehavior==2)) { + e->song.delayBehavior=2; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("no checks (like FamiTracker)"); + } + ImGui::Separator(); ImGui::TextWrapped("the following flags are for compatibility with older Furnace versions."); From 629cca9df19560e34af4586337e9f1207fe1214e Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 22 Aug 2022 00:01:21 -0500 Subject: [PATCH 4/5] ECxx --- src/engine/playback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index fbd9e8db3..8c8fa5729 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -707,7 +707,7 @@ void DivEngine::processRow(int i, bool afterDelay) { dispatchCmd(DivCommand(DIV_CMD_SAMPLE_BANK,i,effectVal)); break; case 0xec: // delayed note cut - if (effectVal>0 && effectVal0 && (song.delayBehavior==2 || effectVal Date: Mon, 22 Aug 2022 00:20:40 -0500 Subject: [PATCH 5/5] allow it --- src/engine/playback.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 8c8fa5729..f4c4968d1 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -382,6 +382,8 @@ void DivEngine::processRow(int i, bool afterDelay) { } } if (returnAfterPre) return; + } else { + logV("honoring delay at position %d",whatRow); } if (chan[i].delayLocked) return; @@ -903,7 +905,9 @@ void DivEngine::nextRow() { prevRow=curRow; for (int i=0; i