dev110 - add cut/delay effect policy compat flag

INCOMPLETE!!!
This commit is contained in:
tildearrow 2022-08-21 23:56:58 -05:00
parent b223bc80de
commit 38afdd3378
5 changed files with 45 additions and 5 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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<nextSpeed);
if (song.delayBehavior==2) comparison=true;
if (comparison) {
chan[i].rowDelay=effectVal+1;
chan[i].delayOrder=whatOrder;
chan[i].delayRow=whatRow;
@ -372,6 +374,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
}
returnAfterPre=true;
} else {
logV("higher than nextSpeed! %d>%d",effectVal,nextSpeed);
chan[i].delayLocked=false;
}
}

View file

@ -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),

View file

@ -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.");