diff --git a/papers/format.md b/papers/format.md index 5dd7d206a..7bd3bba7e 100644 --- a/papers/format.md +++ b/papers/format.md @@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1). the format versions are: +- 108: Furnace dev108 - 107: Furnace dev107 - 106: Furnace dev106 - 105: Furnace dev105 @@ -331,7 +332,8 @@ size | description 1 | broken outVol (>=99) or reserved 1 | E1xy and E2xy stop on same note (>=100) or reserved 1 | broken initial position of porta after arp (>=101) or reserved - 7 | reserved + 1 | SN periods under 8 are treated as 1 (>=108) or reserved + 6 | reserved --- | **virtual tempo data** 2 | virtual tempo numerator of first song (>=96) or reserved 2 | virtual tempo denominator of first song (>=96) or reserved diff --git a/src/engine/engine.h b/src/engine/engine.h index d86e532bb..4f11e82e8 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 "dev107" -#define DIV_ENGINE_VERSION 107 +#define DIV_VERSION "dev108" +#define DIV_ENGINE_VERSION 108 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 196721afa..df32f0553 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -175,6 +175,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.brokenOutVol=true; // ??? ds.e1e2StopOnSameNote=true; ds.brokenPortaArp=false; + ds.snNoLowPeriods=true; // 1.1 compat flags if (ds.version>24) { @@ -1063,6 +1064,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { if (ds.version<101) { ds.brokenPortaArp=true; } + if (ds.version<108) { + ds.snNoLowPeriods=true; + } ds.isDMF=false; reader.readS(); // reserved @@ -1475,7 +1479,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } else { reader.readC(); } - for (int i=0; i<7; i++) { + if (ds.version>=108) { + ds.snNoLowPeriods=reader.readC(); + } else { + reader.readC(); + } + for (int i=0; i<6; i++) { reader.readC(); } } @@ -3719,7 +3728,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) { w->writeC(song.brokenOutVol); w->writeC(song.e1e2StopOnSameNote); w->writeC(song.brokenPortaArp); - for (int i=0; i<7; i++) { + w->writeC(song.snNoLowPeriods); + for (int i=0; i<6; i++) { w->writeC(0); } diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 2988be2f8..40a8616ef 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -188,7 +188,11 @@ void DivPlatformSMS::tick(bool sysTick) { if (chan[i].freqChanged) { chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2,chipClock,toneDivider); if (chan[i].freq>1023) chan[i].freq=1023; - if (chan[i].freq<8) chan[i].freq=1; + if (parent->song.snNoLowPeriods) { + if (chan[i].freq<8) chan[i].freq=1; + } else { + if (chan[i].freq<0) chan[i].freq=0; + } //if (chan[i].actualNote>0x5d) chan[i].freq=0x01; rWrite(0,0x80|i<<5|(chan[i].freq&15)); rWrite(0,chan[i].freq>>4); @@ -203,7 +207,9 @@ void DivPlatformSMS::tick(bool sysTick) { if (chan[3].freqChanged || updateSNMode) { chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,true,0,chan[3].pitch2,chipClock,noiseDivider); if (chan[3].freq>1023) chan[3].freq=1023; - if (chan[3].actualNote>0x5d) chan[3].freq=0x01; + if (parent->song.snNoLowPeriods) { + if (chan[3].actualNote>0x5d) chan[3].freq=0x01; + } if (snNoiseMode&2) { // take period from channel 3 if (updateSNMode || resetPhase) { if (snNoiseMode&1) { diff --git a/src/engine/song.h b/src/engine/song.h index de422a24a..30f5ef245 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -500,6 +500,7 @@ struct DivSong { bool brokenOutVol; bool e1e2StopOnSameNote; bool brokenPortaArp; + bool snNoLowPeriods; std::vector ins; std::vector wave; @@ -600,7 +601,8 @@ struct DivSong { volMacroLinger(true), brokenOutVol(false), e1e2StopOnSameNote(false), - brokenPortaArp(false) { + brokenPortaArp(false), + snNoLowPeriods(false) { for (int i=0; i<32; i++) { system[i]=DIV_SYSTEM_NULL; systemVol[i]=64; diff --git a/src/gui/compatFlags.cpp b/src/gui/compatFlags.cpp index 9024992e7..e6d0aed85 100644 --- a/src/gui/compatFlags.cpp +++ b/src/gui/compatFlags.cpp @@ -139,6 +139,10 @@ void FurnaceGUI::drawCompatFlags() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("if enabled, no checks for the presence of a volume macro will be made.\nthis will cause the last macro value to linger unless a value in the volume column is present."); } + ImGui::Checkbox("Treat SN76489 periods under 8 as 1",&e->song.snNoLowPeriods); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("when enabled, any SN period under 8 will be written as 1 instead.\nthis replicates DefleMask behavior, but reduces available period range."); + } ImGui::Text("Pitch linearity:"); if (ImGui::RadioButton("None",e->song.linearPitch==0)) {